home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume4 / 68kdisassem / part2 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  57.7 KB

  1. From: turner@imagen.UUCP <talcott!topaz!Shasta!imagen!Jim.Turner>
  2. Subject: unc - 68000 disassembler (Part 2 of 2)
  3. Newsgroups: mod.sources
  4. Approved: jpn@panda.UUCP
  5.  
  6. Mod.sources:  Volume 4, Issue 31
  7. Submitted by: turner@imagen.UUCP <talcott!topaz!Shasta!imagen!Jim.Turner>
  8.  
  9. #! /bin/sh
  10. # This is a shell archive, meaning:
  11. # 1. Remove everything above the #! /bin/sh line.
  12. # 2. Save the resulting text in a file.
  13. # 3. Execute the file with /bin/sh (not csh) to create the files:
  14. #    iset.c
  15. #    libmtch.c
  16. #    main.c
  17. #    prin.c
  18. #    robj.c
  19. # This archive created: Thu Mar 13 18:56:11 1986
  20. export PATH; PATH=/bin:$PATH
  21. echo shar: extracting "'iset.c'" '(19541 characters)'
  22. if test -f 'iset.c'
  23. then
  24.     echo shar: will not over-write existing file "'iset.c'"
  25. else
  26. cat << \SHAR_EOF > 'iset.c'
  27. /*
  28.  *    SCCS:    @(#)iset.c    1.2    11/2/84    14:18:23
  29.  *    Decode instructions.
  30.  *
  31.  ***********************************************************************
  32.  *    This software is copyright of
  33.  *
  34.  *        John M Collins
  35.  *        47 Cedarwood Drive
  36.  *        St Albans
  37.  *        Herts, AL4 0DN
  38.  *        England            +44 727 57267
  39.  *
  40.  *    and is released into the public domain on the following conditions:
  41.  *
  42.  *        1.  No free maintenance will be guaranteed.
  43.  *        2.  Nothing may be based on this software without
  44.  *            acknowledgement, including incorporation of this
  45.  *            notice.
  46.  *
  47.  *    Notwithstanding the above, the author welcomes correspondence and bug
  48.  *    fixes.
  49.  ***********************************************************************
  50.  */
  51.  
  52. #include <stdio.h>
  53. #include <a.out.h>
  54. #include "unc.h"
  55.  
  56. ef_fids    mainfile;
  57. long    endt;
  58.  
  59. void    gette(), putte();
  60. void    mkdref();
  61. long    gettw();
  62. symbol    textlab();
  63.  
  64. int    l1(), l2(), el1(), lea(), lmove(), lcbch(), jj();
  65. int    limed(), lsbit(), lmvml(), lone(), loone(), lonew(), lonel();
  66.  
  67. int    pmove(), pcbch(), pdbcc(), pscc(), pcs(), pmovc(), pstop(), pexg();
  68. int    pimed(), pmovp(), psbit(), pdbit(), pcs2(), pone(), ppea();
  69. int    plea(), pdreg(), pmvml(), ptrap(), plink(), pareg(), podreg();
  70. int    pqu(), pmqu(), ptreg(), pcmpm(), pomode(), pmshf(), pshf();
  71.  
  72. struct    opstr    {
  73.     unsigned  short     mask;
  74.     unsigned  short  match;
  75.     int    (*opsize)();
  76.     int    (*opprin)();
  77.     char    *prarg;
  78. } optab[] = {
  79.     0xf000, 0x2000, lmove, pmove, "l",
  80.     0xf000, 0x3000, lmove, pmove, "w",
  81.     0xf000, 0x1000, lmove, pmove, "b",
  82.     0xf000, 0x6000, lcbch, pcbch, 0,
  83.     0xffbf, 0x003c, l2,    pcs,   "or",
  84.     0xff00, 0x0000, limed, pimed, "or",
  85.     0xffbf, 0x023c, l2,    pcs,   "and",
  86.     0xff00, 0x0200, limed, pimed, "and",
  87.     0xff00, 0x0400, limed, pimed, "sub",
  88.     0xff00, 0x0600, limed, pimed, "add",
  89.     0xffbf, 0x0a3c, l2,    pcs,   "eor",
  90.     0xff00, 0x0a00, limed, pimed, "eor",
  91.     0xff00, 0x0c00, limed, pimed, "cmp",
  92.     0xf138, 0x0108, l2,    pmovp, 0,
  93.     0xff00, 0x0800, lsbit, psbit, 0,
  94.     0xf100, 0x0100, lonew, pdbit, 0,
  95.     0xffc0, 0x40c0, lonew, pcs2,  "sr",
  96.     0xff00, 0x4000, lone,  pone,  "negx",
  97.     0xff00, 0x4200, lone,  pone,  "clr",
  98.     0xffc0, 0x44c0, lonew, pcs2,  "cc",
  99.     0xff00, 0x4400, lone,  pone,  "neg",
  100.     0xffc0, 0x46c0, lonew, pcs2,  "sr",
  101.     0xff00, 0x4600, lone,  pone,  "not",
  102.     0xffc0, 0x4800, lonew, ppea,  "nbcd",
  103.     0xfff8, 0x4840, l1,    pdreg, "swap",
  104.     0xffc0, 0x4840, lonel, ppea,  "pea",
  105.     0xfff8, 0x4880, l1,    pdreg, "extw",
  106.     0xfff8, 0x48c0, l1,    pdreg, "extl",
  107.     0xfb80, 0x4880, lmvml, pmvml, 0,
  108.     0xffc0, 0x4ac0, lonew, ppea,  "tas",
  109.     0xff00, 0x4a00, lone,  pone,  "tst",
  110.     0xfff0, 0x4e40, l1,    ptrap, 0,
  111.     0xfff8, 0x4e50, l2,    plink, 0,
  112.     0xfff8, 0x4e58, l1,    pareg, "unlk\t%s",
  113.     0xfff8, 0x4e60, l1,    pareg, "movl\t%s,usp",
  114.     0xfff8, 0x4e68, l1,    pareg, "movl\tusp,%s",
  115.     0xffff, 0x4e70, l1,    pareg, "reset",
  116.     0xffff, 0x4e71, l1,    pareg, "nop",
  117.     0xffff, 0x4e72, l2,    pstop, 0,
  118.     0xffff, 0x4e73, el1,   pareg, "rte",
  119.     0xffff, 0x4e75, el1,   pareg, "rts",
  120.     0xffff, 0x4e76, l1,    pareg, "trapv",
  121.     0xffff, 0x4e77, el1,   pareg, "rtr",
  122.     0xfffe, 0x4e7a, l2,    pmovc, 0,
  123.     0xffc0, 0x4e80, jj,    ppea,  "jsr",
  124.     0xffc0, 0x4ec0, jj,    ppea,  "jmp",
  125.     0xf1c0, 0x4180, lonew, podreg,"chk",
  126.     0xf1c0, 0x41c0, lonel, plea,  0,
  127.     0xf0f8, 0x50c8, lcbch, pdbcc, 0,
  128.     0xf0c0, 0x50c0, lonew, pscc,  0,
  129.     0xf100, 0x5000, lone,  pqu,   "add",
  130.     0xf100, 0x5100, lone,  pqu,   "sub",
  131.     0xf100, 0x7000, l1,    pmqu,  0,
  132.     0xf1c0, 0x80c0, lonew, podreg,"divu",
  133.     0xf1c0, 0x81c0, lonew, podreg,"divs",
  134.     0xf1f0, 0x8100, l1,    ptreg, "sbcd",
  135.     0xf000, 0x8000, loone, pomode,"or",
  136.     0xf1f0, 0x9100, l1,    ptreg, "subxb",
  137.     0xf1f0, 0x9140, l1,    ptreg, "subxw",
  138.     0xf1f0, 0x9180, l1,    ptreg, "subxl",
  139.     0xf000, 0x9000, loone, pomode,"sub",
  140.     0xf1f8, 0xb108, l1,    pcmpm, "cmpmb",
  141.     0xf1f8, 0xb148, l1,    pcmpm, "cmpmw",
  142.     0xf1f8, 0xb188, l1,    pcmpm, "cmpml",
  143.     0xf100, 0xb000, loone, pomode,"cmp",
  144.     0xf1c0, 0xb1c0, loone, pomode,"cmp",
  145.     0xf100, 0xb100, loone, pomode,"eor",
  146.     0xf1c0, 0xc0c0, lonew, podreg,"mulu",
  147.     0xf1c0, 0xc1c0, lonew, podreg,"muls",
  148.     0xf1f0, 0xc100, l1,    ptreg, "abcd",
  149.     0xf130, 0xc100, l1,    pexg,  0,
  150.     0xf000, 0xc000, loone, pomode,"and",
  151.     0xf1f0, 0xd100, l1,    ptreg, "addxb",
  152.     0xf1f0, 0xd140, l1,    ptreg, "addxw",
  153.     0xf1f0, 0xd180, l1,    ptreg, "addxl",
  154.     0xf000, 0xd000, loone, pomode,"add",
  155.     0xf8c0, 0xe0c0, lonew, pmshf,  0,
  156.     0xf000, 0xe000, l1,    pshf,   0,
  157.     0
  158. };
  159.  
  160. char    *areg[] = { "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp"};
  161. char    *cclist[] = { "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs",
  162.             "pl", "mi", "ge", "lt", "gt", "le"};
  163.     
  164. char    *shtype[] = { "as", "ls", "rox", "ro" };
  165. char    *bittyp[] = { "tst", "chg", "clr", "set" };
  166.  
  167. char    *creg[] = { "sfc", "dfc", "usp", "vbr" };
  168.  
  169. /*
  170.  *    Length functions.
  171.  */
  172.  
  173. int    l1()
  174. {
  175.     return    1;
  176. }
  177.  
  178. int    l2()
  179. {
  180.     return    2;
  181. }
  182.  
  183. int    el1(te)
  184. t_entry    *te;
  185. {
  186.     te->t_bchtyp = T_UNBR;
  187.     return    1;
  188. }
  189.  
  190. int    lea(instr, size, pos)
  191. unsigned  instr, size;
  192. long    pos;
  193. {
  194.     switch  ((instr >> 3) & 0x7)  {
  195.     case  0:
  196.     case  1:
  197.     case  2:
  198.     case  3:
  199.     case  4:
  200.         return    1;
  201.     case  5:
  202.     case  6:
  203.         return    2;
  204.     default:
  205.         switch  (instr & 0x7)  {
  206.         case  0:
  207.         case  2:
  208.         case  3:
  209.             return    2;
  210.         case  1:
  211.             mkdref(pos, size);
  212.             return    3;
  213.         case  4:
  214.             if  (size > 2)
  215.                 return    3;
  216.             return    2;
  217.         default:
  218.             return    0;
  219.         }
  220.     }
  221. }
  222.  
  223. /*
  224.  *    Lengths of move instructions.
  225.  */
  226.  
  227. int    lmove(te, pos)
  228. t_entry    *te;
  229. long    pos;
  230. {
  231.     register  unsigned  tc  =  te->t_contents;
  232.     unsigned  sz  =  1;
  233.     int    lng, lng2;
  234.     
  235.     lng  = tc & 0xf000;
  236.     if  (lng == 0x3000)
  237.         sz = 2;
  238.     else  if  (lng == 0x2000)
  239.         sz = 4;
  240.     
  241.     if  ((lng = lea(tc, sz, pos+2)) <= 0)
  242.         return    0;
  243.     lng2 = lea(((tc>>3) & 0x38) | ((tc>>9) & 0x7), sz, pos+lng+lng);
  244.     if  (lng2 <= 0)
  245.         return    0;
  246.     return    lng + lng2 - 1;
  247. }
  248.  
  249. /*
  250.  *    Lengths for conditional branches and dbcc instructions.
  251.  */
  252.  
  253. int    lcbch(te, pos)
  254. t_entry    *te;
  255. long    pos;
  256. {
  257.     unsigned  tc  =  te->t_contents;
  258.     long    dest  =  pos + 2;
  259.     int    res   =  2;
  260.     
  261.     if  ((tc & 0xf000) == 0x5000  ||  (tc & 0xff) == 0)
  262.         dest += (short)gettw(&mainfile, pos+2, R_WORD);
  263.     else  {
  264.         dest += (char) tc;
  265.         res = 1;
  266.     }
  267.     if  ((tc & 0xff00) == 0x6000)
  268.         te->t_bchtyp = T_UNBR;
  269.     else  if  ((tc & 0xff00) == 0x6100)
  270.         te->t_bchtyp = T_JSR;
  271.     else
  272.         te->t_bchtyp = T_CONDBR;
  273.  
  274.     te->t_relsymb = textlab(dest, pos);
  275.     return    res;
  276. }
  277.  
  278. int    jj(te, pos)
  279. t_entry    *te;
  280. long    pos;
  281. {
  282.     unsigned  tc  =  te->t_contents;
  283.     t_entry    nextl;
  284.     
  285.     te->t_bchtyp = (tc & 0x40)? T_UNBR: T_JSR;
  286.     if  ((tc & 0x3f) == 0x39)  {
  287.         gette(&mainfile, pos+2, &nextl);
  288.         if  (nextl.t_relsymb == NULL)  {
  289.             nextl.t_relsymb = textlab(gettw(&mainfile, pos+2, R_LONG), pos);
  290.             putte(&mainfile, pos+2, &nextl);
  291.         }
  292.         te->t_relsymb = nextl.t_relsymb;    /*  Easy ref  */
  293.     }
  294.     return    lea(tc, 4, pos+2);
  295. }
  296.  
  297. int    limed(te, pos)
  298. t_entry    *te;
  299. long    pos;
  300. {
  301.     unsigned  tc  =  te->t_contents;
  302.     int    lng;
  303.     
  304.     /*
  305.      *    Specifically exclude byte address register operands,
  306.      *    and ones which have lengths of 3.
  307.      */
  308.  
  309.     if  ((tc & 0xf8) == 0x08)
  310.         return  0;
  311.     
  312.     if  ((tc & 0xc0) >= 0x80)  {
  313.         if  (tc & 0x40)
  314.             return  0;
  315.         lng = lea(tc, 4, pos+6);
  316.         if  (lng > 0)
  317.             lng += 2;
  318.     }
  319.     else  {
  320.         lng = lea(tc, (unsigned)((tc & 0xc0)?2:1), pos+4);
  321.         if  (lng > 0)
  322.             lng++;
  323.     }
  324.     return    lng;
  325. }
  326.  
  327. int    lsbit(te, pos)
  328. t_entry    *te;
  329. long    pos;
  330. {
  331.     int    lng = lea(te->t_contents, 1, pos+4);
  332.     
  333.     if  (lng > 0)
  334.         lng++;
  335.     return    lng;
  336. }
  337.  
  338. int    lmvml(te, pos)
  339. t_entry    *te;
  340. long    pos;
  341. {
  342.     int    lng = lea(te->t_contents,
  343.             (unsigned)(te->t_contents&0x40? 4:2), pos+4);
  344.     
  345.     if  (lng > 0)
  346.         lng++;
  347.     return    lng;
  348. }
  349.  
  350. /*
  351.  *    Length depends on bits 6 and 7 of instruction.
  352.  */
  353.  
  354. int    lone(te, pos)
  355. t_entry    *te;
  356. long    pos;
  357. {
  358.     unsigned  tc  =  te->t_contents;
  359.     
  360.     return    lea(tc, 1 << ((tc >> 6) & 3), pos+2);
  361. }
  362.  
  363. /*
  364.  *    Length depends on bits 6-8 of instruction.
  365.  */
  366.  
  367. int    loone(te, pos)
  368. t_entry    *te;
  369. long    pos;
  370. {
  371.     unsigned  tc  =  te->t_contents;
  372.     
  373.     switch  ((tc >> 6) & 7)  {
  374.     case  0:
  375.     case  4:
  376.         return    lea(tc, 1, pos+2);
  377.     case  1:
  378.     case  3:
  379.     case  5:
  380.         return  lea(tc, 2, pos+2);
  381.     case  2:
  382.     case  6:
  383.     case  7:
  384.         return    lea(tc, 4, pos+2);
  385.     }
  386.     /*NOTREACHED*/
  387. }
  388.  
  389. int    lonew(te, pos)
  390. t_entry    *te;
  391. long    pos;
  392. {
  393.     return    lea(te->t_contents, 2, pos+2);
  394. }
  395.  
  396. int    lonel(te, pos)
  397. t_entry    *te;
  398. long    pos;
  399. {
  400.     return    lea(te->t_contents, 4, pos+2);
  401. }
  402.  
  403. /*
  404.  *    Print routines.
  405.  */
  406.  
  407. int    findleng(tc)
  408. unsigned  tc;
  409. {
  410.     switch  ((tc >> 6) & 3)  {
  411.     case  0:
  412.         return    'b';
  413.     case  1:
  414.         return    'w';
  415.     default:
  416.         return    'l';
  417.     }
  418. }
  419.  
  420. void    piword(disp)
  421. unsigned  disp;
  422. {
  423.     int    szc;
  424.     
  425.     (void) printf("@(0x%x,", disp & 0xff);
  426.     if  (disp & 0x8000)
  427.         (void) printf("%s", areg[(disp >> 12) & 0x7]);
  428.     else
  429.         (void) printf("d%d", (disp >> 12) & 0x7);
  430.     szc = 'w';
  431.     if  (disp & (1 << 10))
  432.         szc = 'l';
  433.     (void) printf(":%c)", szc);
  434. }
  435.  
  436. void    paddr(pos)
  437. long    pos;
  438. {
  439.     t_entry    tent;
  440.     symbol    symb;
  441.     
  442.     gette(&mainfile, pos, &tent);
  443.     if  (tent.t_relsymb != NULL)  {
  444.         symb = tent.t_relsymb;
  445.         if  (symb->s_lsymb != 0)
  446.             (void) printf("%u$", symb->s_lsymb);
  447.         else
  448.             (void) printf("%s", symb->s_name);
  449.         if  (tent.t_reldisp != 0)
  450.             (void) printf("+0x%x", tent.t_reldisp);
  451.         return;
  452.     }
  453.     (void) printf("0x%x", gettw(&mainfile, pos, R_LONG));
  454. }
  455.  
  456. int    prea(ea, pos, sz)
  457. unsigned  ea, sz;
  458. long    pos;            /*  Address of previous word to extn  */
  459. {
  460.     unsigned  reg  =  ea & 0x7;
  461.     long    disp;
  462.     
  463.     pos += 2;
  464.     
  465.     switch  ((ea >> 3) & 0x7)  {
  466.     case  0:
  467.         (void) printf("d%d", reg);
  468.         return    0;
  469.     case  1:
  470.         (void) printf("%s", areg[reg]);
  471.         return    0;
  472.     case  2:
  473.         (void) printf("%s@", areg[reg]);
  474.         return    0;
  475.     case  3:
  476.         (void) printf("%s@+", areg[reg]);
  477.         return    0;
  478.     case  4:
  479.         (void) printf("%s@-", areg[reg]);
  480.         return    0;
  481.     case  5:
  482.         disp = gettw(&mainfile, pos, R_WORD);
  483.         (void) printf("%s@(0x%x)", areg[reg], disp);
  484.         return    2;
  485.     case  6:
  486.         (void) printf("%s", areg[reg]);
  487.         piword((unsigned) gettw(&mainfile, pos, R_WORD));
  488.         return    2;
  489.     default:
  490.         switch  (reg)  {
  491.         case  0:
  492.             disp = gettw(&mainfile, pos, R_WORD);
  493.             (void) printf("0x%x:w", disp);
  494.             return    2;
  495.         case  1:
  496.             paddr(pos);
  497.             return    4;
  498.         case  2:
  499.             disp = gettw(&mainfile, pos, R_WORD);
  500.             (void) printf("pc@(0x%x)", disp);
  501.             return    2;
  502.         case  3:
  503.             (void) printf("pc");
  504.             piword((unsigned) gettw(&mainfile, pos, R_WORD));
  505.             return    2;
  506.         case  4:
  507.             (void) printf("#");
  508.             if  (sz < 4)
  509.                 (void) printf("0x%x", gettw(&mainfile, pos, R_WORD));
  510.             else
  511.                 paddr(pos);
  512.             return    sz;
  513.         default:
  514.             (void) fprintf(stderr, "Funny mode\n");
  515.             exit(220);
  516.         }
  517.     }
  518.     /*NOTREACHED*/
  519. }
  520.     
  521. int    pmove(te, pos)
  522. t_entry    *te;
  523. long    pos;
  524. {
  525.     unsigned  sz  =  2;
  526.     unsigned  tc  =  te->t_contents;
  527.     
  528.     (void) printf("mov%s\t", optab[te->t_iindex].prarg);
  529.     
  530.     if  ((tc & 0xf000) == 0x2000)
  531.         sz = 4;
  532.     
  533.     pos += prea(tc, pos, sz);
  534.     putchar(',');
  535.     (void) prea(((tc >> 9) & 0x7) | ((tc >> 3) & 0x38), pos, sz);
  536. }
  537.  
  538. int    pcbch(te)
  539. t_entry    *te;
  540. {
  541.     int    cc = ((te->t_contents >> 8) & 0xf) - 2;
  542.     char    *msg;
  543.     register  symbol  ts;
  544.     
  545.     if  (cc < 0)
  546.         msg = cc < -1? "ra": "sr";
  547.     else
  548.         msg = cclist[cc];
  549.     (void) printf("b%s", msg);
  550.     if  (te->t_lng < 2)
  551.         (void) printf("s");
  552.     ts = te->t_relsymb;
  553.     if  (ts->s_lsymb != 0)
  554.         (void) printf("\t%u$", ts->s_lsymb);
  555.     else
  556.         (void) printf("\t%s", ts->s_name);
  557. }
  558.  
  559. int    pdbcc(te)
  560. t_entry    *te;
  561. {
  562.     unsigned  tc  =  te->t_contents;
  563.     int    cc = ((tc >> 8) & 0xf) - 2;
  564.     char    *msg;
  565.     register  symbol  ts;
  566.     
  567.     if  (cc < 0)
  568.         msg = cc < -1? "t": "f";
  569.     else
  570.         msg = cclist[cc];
  571.     ts = te->t_relsymb;
  572.     (void) printf("db%s\td%d,", msg, tc & 0x7);
  573.     if  (ts->s_lsymb)
  574.         (void) printf("%u$", ts->s_lsymb);
  575.     else
  576.         (void) printf("%s", ts->s_name);
  577. }
  578.  
  579. int    pscc(te, pos)
  580. t_entry    *te;
  581. long    pos;
  582. {
  583.     unsigned  tc  =  te->t_contents;
  584.     int    cc = ((tc >> 8) & 0xf) - 2;
  585.     char    *msg;
  586.     
  587.     if  (cc < 0)
  588.         msg = cc < -1? "t": "f";
  589.     else
  590.         msg = cclist[cc];
  591.     (void) printf("s%s\t", msg);
  592.     (void) prea(tc, pos, 1);
  593. }
  594.  
  595. int    pcs(te, pos)
  596. t_entry    *te;
  597. long    pos;
  598. {
  599.     long    disp  =  gettw(&mainfile, pos+2, R_WORD);
  600.     
  601.     (void) printf("%s", optab[te->t_iindex].prarg);
  602.     if  ((te->t_contents & 0xc0) == 0)
  603.         (void) printf("b\t#0x%x,cc", disp);
  604.     else
  605.         (void) printf("w\t#0x%x,sr", disp);
  606. }
  607.  
  608. int    pmovc(te, pos)
  609. t_entry    *te;
  610. long    pos;
  611. {
  612.     int    disp = gettw(&mainfile, pos+2, R_WORD);
  613.     int    ctrl = ((disp >> 10) & 2) | (disp & 1);
  614.  
  615.     (void) printf("movec\t");
  616.     if  ((te->t_contents & 1) == 0)
  617.         (void) printf("%s,", creg[ctrl]);
  618.     if  (disp & 0x8000)
  619.         (void) printf("%s", areg[(disp >> 12) & 7]);
  620.     else
  621.         (void) printf("d%d", disp >> 12);
  622.     if  (te->t_contents & 1)
  623.         (void) printf(",%s", creg[ctrl]);
  624. }
  625.  
  626. int    pimed(te, pos)
  627. t_entry    *te;
  628. long    pos;
  629. {
  630.     int    sz = findleng(te->t_contents);
  631.     
  632.     (void) printf("%s%c\t#", optab[te->t_iindex].prarg, sz);
  633.     if  (sz == 'l')  {
  634.         paddr(pos+2);
  635.         putchar(',');
  636.         (void) prea(te->t_contents, pos+4, 4);
  637.     }
  638.     else  {
  639.         (void) printf("0x%x,", gettw(&mainfile, pos+2, R_WORD));
  640.         (void) prea(te->t_contents, pos+2, 2);
  641.     }
  642. }
  643.  
  644. int    pmovp(te, pos)
  645. t_entry    *te;
  646. long    pos;
  647. {
  648.     unsigned  tc  =  te->t_contents;
  649.     long    disp  =  gettw(&mainfile, pos+2, R_WORD);
  650.     int    dreg = tc >> 9;
  651.     char    *ar = areg[tc & 0x7];
  652.     
  653.     (void) printf("movep");
  654.     if  (tc & (1 << 6))
  655.         putchar('l');
  656.     else
  657.         putchar('w');
  658.  
  659.     if  (tc & (1 << 7))
  660.         (void) printf("\td%d,%s@(0x%x)", dreg, ar, disp);
  661.     else
  662.         (void) printf("\t%s@(0x%x),d%d", ar, disp, dreg);
  663. }
  664.  
  665. int    psbit(te, pos)
  666. t_entry    *te;
  667. long    pos;
  668. {
  669.     unsigned  tc  =  te->t_contents;
  670.     
  671.     (void) printf("b%s\t#%d,", bittyp[(tc >> 6) & 0x3], gettw(&mainfile, pos+2, R_WORD));
  672.     (void) prea(tc, pos+2, 1);
  673. }
  674.  
  675. /*ARGSUSED*/
  676. int    pstop(te, pos)
  677. t_entry    *te;
  678. long    pos;
  679. {
  680.     (void) printf("stop\t#0x%x", gettw(&mainfile, pos+2, R_WORD));
  681. }
  682.  
  683. int    pdbit(te, pos)
  684. t_entry    *te;
  685. long    pos;
  686. {
  687.     unsigned  tc  =  te->t_contents;
  688.     
  689.     (void) printf("b%s\td%d,", bittyp[(tc >> 6) & 0x3], (tc >> 9) & 0x7);
  690.     (void) prea(tc, pos, 1);
  691. }
  692.  
  693. int    pcs2(te, pos)
  694. t_entry    *te;
  695. long    pos;
  696. {
  697.     unsigned  tc  =  te->t_contents;
  698.     
  699.     (void) printf("movw\t");
  700.     if  ((tc & 0xffc0) == 0x40c0)  {
  701.         (void) printf("sr,");
  702.         (void) prea(tc, pos, 2);
  703.     }
  704.     else  {
  705.         (void) prea(tc, pos, 2);
  706.         (void) printf(",%s", optab[te->t_iindex].prarg);
  707.     }
  708. }
  709.  
  710. int    pone(te, pos)
  711. t_entry    *te;
  712. long    pos;
  713. {
  714.     unsigned  tc  =  te->t_contents;
  715.     int    sz = findleng(tc);
  716.     
  717.     (void) printf("%s%c\t", optab[te->t_iindex].prarg, sz);
  718.     (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  719. }
  720.  
  721. int    ppea(te, pos)    /*  nbcd, pea, tas, jmp, jsr  */
  722. t_entry    *te;
  723. long    pos;
  724. {
  725.     (void) printf("%s\t", optab[te->t_iindex].prarg);
  726.     (void) prea(te->t_contents, pos, (unsigned)(te->t_lng > 2? 4: 2));
  727. }
  728.  
  729.  
  730. int    plea(te, pos)
  731. t_entry    *te;
  732. long    pos;
  733. {
  734.     (void) printf("lea\t");
  735.     (void) prea(te->t_contents, pos, 4);
  736.     (void) printf(",%s", areg[(te->t_contents >> 9) & 0x7]);
  737. }
  738.  
  739. int    pdreg(te)
  740. t_entry    *te;
  741. {
  742.     (void) printf("%s\td%d", optab[te->t_iindex].prarg, te->t_contents & 7);
  743. }
  744.  
  745.  
  746. int    pmvml(te, pos)
  747. t_entry    *te;
  748. long    pos;
  749. {
  750.     unsigned  tc  =  te->t_contents;
  751.     register  unsigned  dw  =  gettw(&mainfile, pos+2, R_WORD);
  752.     unsigned  sz = 4;
  753.     int    sc = 'l';
  754.     register  int    i;
  755.     register  unsigned  bit;
  756.     
  757.     (void) printf("movem");
  758.     if  ((tc & 0x40) == 0)  {
  759.         sc = 'w';
  760.         sz = 2;
  761.     }
  762.     
  763.     (void) printf("%c\t", sc);
  764.     
  765.     if  (tc & 0x400)  {
  766.         (void) prea(tc, pos+2, sz);
  767.         (void) printf(",#0x%x", dw);
  768.     }
  769.     else  {
  770.         (void) printf("#0x%x,", dw);
  771.         (void) prea(tc, pos+2, sz);
  772.     }
  773.     
  774.     (void) printf("\t|");
  775.     
  776.     if  ((tc & 0x38) == 0x20)  {
  777.         bit = 0x8000;
  778.         for  (i = 0;  i < 8;  i++)  {
  779.             if  (dw & bit)
  780.                 (void) printf(" d%d", i);
  781.             bit >>= 1;
  782.         }
  783.         for  (i = 0;  i < 8;  i++)  {
  784.             if  (dw & bit)
  785.                 (void) printf(" %s", areg[i]);
  786.             bit >>= 1;
  787.         }
  788.     }
  789.     else  {
  790.         bit = 1;
  791.         for  (i = 0;  i < 8;  i++)  {
  792.             if  (dw & bit)
  793.                 (void) printf(" d%d", i);
  794.             bit <<= 1;
  795.         }
  796.         for  (i = 0;  i < 8;  i++)  {
  797.             if  (dw & bit)
  798.                 (void) printf(" %s", areg[i]);
  799.             bit <<= 1;
  800.         }
  801.     }
  802. }
  803.  
  804. int    ptrap(te)
  805. t_entry    *te;
  806. {
  807.     (void) printf("trap\t#0x%x", te->t_contents & 0xf);
  808. }
  809.  
  810. int    plink(te, pos)
  811. t_entry    *te;
  812. long    pos;
  813. {
  814.     (void) printf("link\t%s,#0x%x", areg[te->t_contents & 0x7],
  815.                 gettw(&mainfile, pos+2, R_WORD));
  816. }
  817.  
  818.  
  819. int    pareg(te)
  820. t_entry    *te;
  821. {
  822.     (void) printf(optab[te->t_iindex].prarg, areg[te->t_contents & 0x7]);
  823. }
  824.  
  825. int    podreg(te, pos)
  826. t_entry    *te;
  827. long    pos;
  828. {
  829.     unsigned  tc  =  te->t_contents;
  830.     
  831.     (void) printf("%s\t", optab[te->t_iindex].prarg);
  832.     (void) prea(tc, pos, 2);
  833.     (void) printf(",d%d", (tc >> 9) & 0x7);
  834. }
  835.  
  836. int    pqu(te, pos)
  837. t_entry    *te;
  838. long    pos;
  839. {
  840.     unsigned  tc  =  te->t_contents;
  841.     int    sz  =  findleng(tc);
  842.     int    amt = (tc >> 9) & 0x7;
  843.     
  844.     if  (amt == 0)
  845.         amt = 8;
  846.     (void) printf("%sq%c\t#%d,", optab[te->t_iindex].prarg, sz, amt);
  847.     (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  848. }
  849.  
  850. int    pmqu(te)
  851. t_entry    *te;
  852. {
  853.     unsigned  tc  =  te->t_contents;
  854.  
  855.     (void) printf("moveq\t#0x%x,d%d", (char)tc, (tc >> 9) & 0x7);
  856. }
  857.  
  858. int    ptreg(te)
  859. t_entry    *te;
  860. {
  861.     register  unsigned  tc  =  te->t_contents;
  862.     int    rx = (tc >> 9) & 0x7;
  863.     int    ry = tc & 0x7;
  864.  
  865.     (void) printf("%s\t", optab[te->t_iindex].prarg);
  866.     if  (tc & 0x8)
  867.         (void) printf("%s@-,%s@-", areg[ry], areg[rx]);
  868.     else
  869.         (void) printf("d%d,d%d", ry, rx);
  870. }
  871.  
  872. int    pcmpm(te)
  873. t_entry    *te;
  874. {
  875.     register  unsigned  tc  =  te->t_contents;
  876.  
  877.     (void) printf("%s\t%s@+,%s@+", optab[te->t_iindex].prarg,
  878.         areg[tc & 7], areg[(tc >> 9) & 7]);
  879. }
  880.  
  881. int    pomode(te, pos)
  882. t_entry    *te;
  883. long    pos;
  884. {
  885.     unsigned  tc  =  te->t_contents;
  886.     char    bef[4], aft[4];
  887.     int    sz;
  888.     int    reg = (tc >> 9) & 7;
  889.  
  890.     bef[0] = aft[0] = '\0';
  891.     
  892.     switch  ((tc >> 6) & 7)  {
  893.     case  0:
  894.         sz = 'b';
  895.         goto  toreg;
  896.     case  1:
  897.         sz = 'w';
  898.         goto  toreg;
  899.     case  2:
  900.         sz = 'l';
  901.     toreg:
  902.         (void) sprintf(aft, ",d%d", reg);
  903.         break;
  904.     case  3:
  905.         sz = 'w';
  906.         goto  toareg;
  907.     case  7:
  908.         sz = 'l';
  909.     toareg:
  910.         (void) sprintf(aft, ",%s", areg[reg]);
  911.         break;
  912.     case  4:
  913.         sz = 'b';
  914.         goto  frreg;
  915.     case  5:
  916.         sz = 'w';
  917.         goto  frreg;
  918.     case  6:
  919.         sz = 'l';
  920.     frreg:
  921.         (void) sprintf(bef, "d%d,", reg);
  922.         break;
  923.     }
  924.  
  925.     (void) printf("%s%c\t%s", optab[te->t_iindex].prarg, sz, bef);
  926.     (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  927.     (void) printf(aft);
  928. }
  929.  
  930. int    pexg(te)
  931. t_entry    *te;
  932. {
  933.     unsigned  tc  =  te->t_contents;
  934.     int    r1 = (tc >> 9) & 7, r2 = tc & 7;
  935.  
  936.     (void) printf("exg\t");
  937.     
  938.     if  ((tc & 0x00f8) == 0x0048)
  939.         (void) printf("%s,", areg[r1]);
  940.     else
  941.         (void) printf("d%d,", r1);
  942.     if  (tc & 0x8)
  943.         (void) printf("%s", areg[r2]);
  944.     else
  945.         (void) printf("d%d", r2);
  946. }
  947.     
  948. int    pmshf(te, pos)
  949. t_entry    *te;
  950. long    pos;
  951. {
  952.     unsigned  tc  =  te->t_contents;
  953.     
  954.     (void) printf("%s%cw\t", shtype[(tc >> 9) & 3], tc & 0x100? 'l': 'r');
  955.     (void) prea(tc, pos, 2);
  956. }
  957.  
  958. int    pshf(te)
  959. t_entry    *te;
  960. {
  961.     unsigned  tc  =  te->t_contents;
  962.     int    sz  =  findleng(tc);
  963.     int    disp = (tc >> 9) & 7;
  964.  
  965.     (void) printf("%s%c%c\t", shtype[(tc >> 3) & 3], tc & 0x100? 'l': 'r', sz);
  966.     if  (tc & 0x20)
  967.         (void) printf("d%d", disp);
  968.     else
  969.         (void) printf("#%d", disp == 0? 8: disp);
  970.     (void) printf(",d%d", tc & 7);
  971. }
  972.  
  973. /*
  974.  *    Find length etc of instruction.
  975.  */
  976.  
  977. int    findinst(te, pos)
  978. register  t_entry  *te;
  979. long    pos;
  980. {
  981.     register  struct  opstr    *op;
  982.     unsigned  tc  =  te->t_contents;
  983.     int    lng = 0;
  984.     register  int    i;
  985.  
  986.     te->t_type = T_BEGIN;
  987.     te->t_bchtyp = T_NOBR;
  988.     
  989.     for  (op = &optab[0];  op->mask;  op++)  {
  990.         if  ((tc & op->mask) == op->match)  {
  991.             te->t_iindex = op - optab;
  992.             lng = (op->opsize)(te, pos);
  993.             break;
  994.         }
  995.     }
  996.  
  997.     for  (i = 1;  i < lng;  i++)  {
  998.         t_entry    ctent;
  999.         long    npos = pos+i+i;
  1000.         
  1001.         if  (npos >= endt)
  1002.             goto  clearem;
  1003.         gette(&mainfile, npos, &ctent);
  1004.         if  (ctent.t_bdest || ctent.t_dref)  {
  1005. clearem:        for  (i--; i > 0; i--)  {
  1006.                 npos = pos + i + i;
  1007.                 gette(&mainfile, npos, &ctent);
  1008.                 ctent.t_type = T_UNKNOWN;
  1009.                 putte(&mainfile, npos, &ctent);
  1010.             }
  1011.             lng = 0;
  1012.             goto  ginv;
  1013.         }
  1014.         ctent.t_type = T_CONT;
  1015.         putte(&mainfile, npos, &ctent);
  1016.     }
  1017.     
  1018.     if  (lng <= 0)  {
  1019. ginv:        te->t_vins = 0;
  1020.         te->t_lng = 1;
  1021.         te->t_type = T_UNKNOWN;
  1022.         te->t_bchtype = T_NOBR;
  1023.     }
  1024.     else
  1025.         te->t_lng = lng;
  1026.     return    lng;
  1027. }
  1028.  
  1029. /*
  1030.  *    Print instruction.
  1031.  */
  1032.  
  1033. void    prinst(te, pos)
  1034. t_entry    *te;
  1035. long    pos;
  1036. {
  1037.     putchar('\t');
  1038.     (optab[te->t_iindex].opprin)(te, pos);
  1039.     putchar('\n');
  1040. }
  1041. SHAR_EOF
  1042. if test 19541 -ne "`wc -c < 'iset.c'`"
  1043. then
  1044.     echo shar: error transmitting "'iset.c'" '(should have been 19541 characters)'
  1045. fi
  1046. fi
  1047. echo shar: extracting "'libmtch.c'" '(7242 characters)'
  1048. if test -f 'libmtch.c'
  1049. then
  1050.     echo shar: will not over-write existing file "'libmtch.c'"
  1051. else
  1052. cat << \SHAR_EOF > 'libmtch.c'
  1053. /*
  1054.  *    SCCS:    @(#)libmtch.c    1.2    11/2/84    14:18:55
  1055.  *    Read library files.
  1056.  *
  1057.  ***********************************************************************
  1058.  *    This software is copyright of
  1059.  *
  1060.  *        John M Collins
  1061.  *        47 Cedarwood Drive
  1062.  *        St Albans
  1063.  *        Herts, AL4 0DN
  1064.  *        England            +44 727 57267
  1065.  *
  1066.  *    and is released into the public domain on the following conditions:
  1067.  *
  1068.  *        1.  No free maintenance will be guaranteed.
  1069.  *        2.  Nothing may be based on this software without
  1070.  *            acknowledgement, including incorporation of this
  1071.  *            notice.
  1072.  *
  1073.  *    Notwithstanding the above, the author welcomes correspondence and bug
  1074.  *    fixes.
  1075.  ***********************************************************************
  1076.  */
  1077.  
  1078. #include <stdio.h>
  1079. #include <fcntl.h>
  1080. #include <a.out.h>
  1081. #include <ar.h>
  1082. #include <setjmp.h>
  1083. #include "unc.h"
  1084.  
  1085. long    lseek();
  1086. void    bfopen(), bfclose(), nomem();
  1087. void    rrell2(), markmatch();
  1088. char    *strchr(), *strrchr(), *strncpy(), *strcat(), *strcpy(), *malloc();
  1089. int    matchup();
  1090. long    findstart();
  1091.  
  1092. char    verbose;        /*  Tell the world what we are doing  */
  1093. char    *tfnam;
  1094. char    *cfile;
  1095. ef_fids    mainfile;
  1096. struct    commit    dreltab;
  1097. int    donedrel, donebrel;
  1098. long    trelpos, drelpos, brelpos;
  1099. static    struct    libit    currlib = {-1, 0, -1, ""};
  1100.  
  1101. void    lclash(str)
  1102. char    *str;
  1103. {
  1104.     (void) fprintf(stderr, "Library scan failure - %s\n", str);
  1105.     (void) fprintf(stderr, "Searching %s\n", cfile);
  1106.     if  (currlib.lf_name[0])
  1107.         (void) fprintf(stderr, "Member is %s\n", currlib.lf_name);
  1108.     exit(255);
  1109. }
  1110.  
  1111. /*
  1112.  *    Find next member.
  1113.  */
  1114.  
  1115. long    nextmemb(lfd)
  1116. register  struct  libit     *lfd;
  1117. {
  1118.     struct    ar_hdr    arbuf;
  1119.     
  1120.     if  (lfd->lf_next < 0)
  1121.         return    -1;
  1122.     
  1123.     (void) lseek(lfd->lf_fd, lfd->lf_next, 0);
  1124.     if  (read(lfd->lf_fd, (char *)&arbuf, sizeof(arbuf)) != sizeof(arbuf))  {
  1125.         lfd->lf_next = -1;
  1126.         return    -1;
  1127.     }
  1128.     (void) strncpy(lfd->lf_name, arbuf.ar_name, sizeof(lfd->lf_name));
  1129.     lfd->lf_offset = lfd->lf_next + sizeof(arbuf);
  1130.     lfd->lf_next = (lfd->lf_offset + arbuf.ar_size + 1) & ~1;
  1131.     return    lfd->lf_offset;
  1132. }
  1133.  
  1134. /*
  1135.  *    Decode a file name thus -
  1136.  *
  1137.  *    -lxxx decode as /lib/libxxx.a /usr/lib/libxxx.a etc
  1138.  *    -Lxxx forget "lib" ".a" bit thus -Lcrt0.o
  1139.  *    or read LDPATH environment var to give list of directories as sh
  1140.  *    (default /lib:/usr/lib).
  1141.  *
  1142.  *    Alternatively treat as normal pathname.
  1143.  *
  1144.  *    File names may be followed by (membername) if the file is an archive,
  1145.  *    thus
  1146.  *
  1147.  *        -lc(printf.o)
  1148.  *
  1149.  *    in which case the specified module is fetched.
  1150.  */
  1151.  
  1152. struct    libit    *getfnam(str)
  1153. char    *str;
  1154. {
  1155.     char    *bp, *ep = NULL, *pathb, *pathe, *fullpath = NULL;
  1156.     static    char    *pathn;
  1157.     extern    char    *getenv();
  1158.     long    magic;
  1159.     struct    ar_hdr    arhdr;
  1160.     int    fd;
  1161.  
  1162.     if  ((bp = strrchr(str, '(')) != NULL &&
  1163.          (ep = strrchr(str, ')')) != NULL)
  1164.         *ep = *bp = '\0';
  1165.  
  1166.     if  (str[0] == '-'  &&  (str[1] == 'l' || str[1] == 'L'))  {
  1167.         if  (pathn == NULL)  {
  1168.             if  ((pathn = getenv("LDPATH")) == NULL)
  1169.                 pathn = "/lib:/usr/lib";
  1170.         }
  1171.         fullpath = malloc((unsigned)(strlen(pathn) + strlen(str) + 1));
  1172.         if  (fullpath == NULL)
  1173.             nomem();
  1174.         pathb = pathn;
  1175.         do  {
  1176.             pathe = strchr(pathb, ':');
  1177.             if  (*pathb == ':')
  1178.                 fullpath[0] = '\0';
  1179.             else  {
  1180.                 if  (pathe != NULL)
  1181.                     *pathe = '\0';
  1182.                 (void) strcpy(fullpath, pathb);
  1183.                 (void) strcat(fullpath, "/");
  1184.                 if  (pathe != NULL)
  1185.                     *pathe = ':';
  1186.             }
  1187.             if  (str[1] == 'l')
  1188.                 (void) strcat(fullpath, "lib");
  1189.             (void) strcat(fullpath, &str[2]);
  1190.             if  (str[1] == 'l')
  1191.                 (void) strcat(fullpath, ".a");
  1192.             if  ((fd = open(fullpath, O_RDONLY)) >= 0)
  1193.                 goto  found;
  1194.             pathb = pathe + 1;
  1195.         }   while  (pathe != NULL);
  1196.         
  1197.         (void) fprintf(stderr, "Unable to locate lib%s.a in %s\n",
  1198.             &str[2], pathn);
  1199.         exit(101);
  1200.     }
  1201.     else  if  ((fd = open(str, O_RDONLY)) < 0)  {
  1202.         (void) fprintf(stderr, "Cannot open %s\n", str);
  1203.         exit(102);
  1204.     }
  1205.     
  1206. found:
  1207.  
  1208.     if  ((read(fd, (char *) &magic, sizeof(magic)) != sizeof(magic)  ||
  1209.         magic != ARMAG))  {
  1210.         if  (ep != NULL)  {
  1211.             (void) fprintf(stderr, "%s is not library file\n",
  1212.                     fullpath != NULL? fullpath: str);
  1213.             exit(103);
  1214.         }
  1215.         if  (fullpath != NULL)
  1216.             free(fullpath);
  1217.         currlib.lf_fd = fd;
  1218.         currlib.lf_offset = 0;
  1219.         currlib.lf_next = -1;
  1220.         currlib.lf_name[0] = '\0';
  1221.         return  &currlib;
  1222.     }
  1223.     
  1224.     /*
  1225.      *    It appears to be a library file - see if we want a specific
  1226.      *    one.
  1227.      */
  1228.     
  1229.     if  (ep != NULL)  {
  1230.         currlib.lf_offset = sizeof(magic) + sizeof(struct ar_hdr);
  1231.         for  (;;)  {
  1232.             if  (read(fd, &arhdr, sizeof(arhdr)) != sizeof(arhdr))  {
  1233.                 (void) fprintf(stderr, "Cannot find member %s in %s\n",
  1234.                     bp+1, fullpath?fullpath: str);
  1235.                 exit(103);
  1236.             }
  1237.             if  (strncmp(bp+1, arhdr.ar_name, sizeof(arhdr.ar_name)) == 0)
  1238.                 break;
  1239.             currlib.lf_offset += arhdr.ar_size + sizeof(arhdr) + 1;
  1240.             currlib.lf_offset &= ~ 1;
  1241.             (void) lseek(fd, (long)(currlib.lf_offset - sizeof(arhdr)), 0);
  1242.         }
  1243.         if  (fullpath != NULL)
  1244.             free(fullpath);
  1245.         currlib.lf_fd = fd;
  1246.         currlib.lf_next = -1;
  1247.         currlib.lf_name[0] = '\0';
  1248.         *bp = '(';
  1249.         *ep = ')';
  1250.         return    &currlib;
  1251.     }
  1252.     
  1253.     /*
  1254.      *    Otherwise point to 1st member in library.
  1255.      */
  1256.     
  1257.     if  (read(fd, &arhdr, sizeof(arhdr)) != sizeof(arhdr))  {
  1258.         (void) fprintf(stderr, "Library %s empty\n", fullpath? fullpath: str);
  1259.         exit(104);
  1260.     }
  1261.     if  (fullpath != NULL)
  1262.         free(fullpath);
  1263.     currlib.lf_offset = sizeof(magic) + sizeof(arhdr);
  1264.     currlib.lf_next = currlib.lf_offset + arhdr.ar_size + 1;
  1265.     currlib.lf_next &= ~1;
  1266.     currlib.lf_fd = fd;
  1267.     (void) strncpy(currlib.lf_name, arhdr.ar_name, sizeof(currlib.lf_name));
  1268.     return    &currlib;
  1269. }
  1270.  
  1271. /*
  1272.  *    Process library files.
  1273.  */
  1274.  
  1275. #define    MINTEXT    6
  1276.  
  1277. void    lscan(nfiles, fnames)
  1278. int    nfiles;
  1279. char    **fnames;
  1280. {
  1281.     ef_fids    libfile;
  1282.     register  ef_fid  ll = &libfile;
  1283.     register  struct  libit     *clf;
  1284.     extern    symbol    dolsymb();
  1285.     int    firstfile;
  1286.     
  1287.     for  (;  nfiles > 0;  fnames++, nfiles--)  {
  1288.         clf = getfnam(*fnames);
  1289.         cfile = *fnames;
  1290.         firstfile = 1;
  1291.         do  {
  1292.             bfopen(tfnam, ll);
  1293.  
  1294.             /*
  1295.              *    If file is garbled, silently forget it and go
  1296.              *    on to the next one.
  1297.              */
  1298.  
  1299.             if  (!rtext(clf->lf_fd, clf->lf_offset, ll))
  1300.                 goto  closeit;
  1301.                 
  1302.             if  (ll->ef_tsize < MINTEXT)
  1303.                 goto  closeit;
  1304.                 
  1305.             if  (!rdata(clf->lf_fd, clf->lf_offset, ll))
  1306.                 goto  closeit;
  1307.                 
  1308.             if  (rrell1(clf->lf_fd, clf->lf_offset, ll) < 0)
  1309.                 goto  closeit;
  1310.                 
  1311.             /*
  1312.              *    If first file in library, find it from
  1313.              *    beginning of main file.
  1314.              */
  1315.             
  1316.             if  (firstfile)  {
  1317.                 if  ((trelpos = findstart(&mainfile, ll)) < 0)
  1318.                     goto  closeit;
  1319.                 firstfile = 0;
  1320.             }
  1321.             else   if  (!matchup(&mainfile, ll, trelpos))
  1322.                     goto  closeit;
  1323.             
  1324.             /*
  1325.              *    Found a match.
  1326.              */
  1327.             
  1328.             if  (!rsymb(clf->lf_fd, clf->lf_offset, dolsymb, ll))  {
  1329.                 (void) fprintf(stderr, "Corrupt file %s\n",
  1330.                             *fnames);
  1331.                 exit(150);
  1332.             }
  1333.             
  1334.             donedrel = 0;
  1335.             donebrel = 0;
  1336.             rrell2(clf->lf_fd, clf->lf_offset, ll);
  1337.             if  (verbose)  {
  1338.                 (void) fprintf(stderr, "Found: ");
  1339.                 if  (clf->lf_name[0])
  1340.                     (void) fprintf(stderr, "%.14s in ",
  1341.                             clf->lf_name);
  1342.                 (void) fprintf(stderr, "%s\n", *fnames);
  1343.             }
  1344.             if  (libfile.ef_stvec != NULL)  {
  1345.                 free(libfile.ef_stvec);
  1346.                 libfile.ef_stvec = NULL;
  1347.                 libfile.ef_stcnt = 0;
  1348.             }
  1349.             dreltab.c_int = 0;
  1350.                 
  1351.             /*
  1352.              *    Start looking next time round
  1353.              *    where last one left off.
  1354.              */
  1355.             
  1356.             markmatch(&mainfile, ll, trelpos);
  1357.             trelpos += libfile.ef_tsize;
  1358. closeit:
  1359.             bfclose(ll);
  1360.         }  while  (nextmemb(clf) >= 0);
  1361.     }
  1362. }
  1363. SHAR_EOF
  1364. if test 7242 -ne "`wc -c < 'libmtch.c'`"
  1365. then
  1366.     echo shar: error transmitting "'libmtch.c'" '(should have been 7242 characters)'
  1367. fi
  1368. fi
  1369. echo shar: extracting "'main.c'" '(6255 characters)'
  1370. if test -f 'main.c'
  1371. then
  1372.     echo shar: will not over-write existing file "'main.c'"
  1373. else
  1374. cat << \SHAR_EOF > 'main.c'
  1375. /*
  1376.  *    SCCS:    @(#)main.c    1.2    11/2/84    14:19:31
  1377.  *    Main routine etc.
  1378.  *
  1379.  ***********************************************************************
  1380.  *    This software is copyright of
  1381.  *
  1382.  *        John M Collins
  1383.  *        47 Cedarwood Drive
  1384.  *        St Albans
  1385.  *        Herts, AL4 0DN
  1386.  *        England            +44 727 57267
  1387.  *
  1388.  *    and is released into the public domain on the following conditions:
  1389.  *
  1390.  *        1.  No free maintenance will be guaranteed.
  1391.  *        2.  Nothing may be based on this software without
  1392.  *            acknowledgement, including incorporation of this
  1393.  *            notice.
  1394.  *
  1395.  *    Notwithstanding the above, the author welcomes correspondence and bug
  1396.  *    fixes.
  1397.  ***********************************************************************
  1398.  */
  1399.  
  1400. #include <stdio.h>
  1401. #include <fcntl.h>
  1402. #include <a.out.h>
  1403. #include <sys/var.h>
  1404. #include "unc.h"
  1405.  
  1406. #define    LINELNG    70
  1407.  
  1408. void    inturdat(), intutext(), intudat(), intlsym();
  1409. void    ptext(), pdata(), pabs(), pbss(), lscan();
  1410.  
  1411. ef_fids    mainfile;
  1412.  
  1413. int    par_entry, par_round;    /*  68000 parameters  */
  1414. int    nmods;            /*  Number of modules it looks like  */
  1415.  
  1416. char    *tfnam = "split";
  1417.  
  1418. char    lsyms;            /*  Generate local symbols  */
  1419. char    verbose;        /*  Tell the world what we are doing  */
  1420. char    noabs;            /*  No non-global absolutes  */
  1421. int    rel;            /*  File being analysed is relocatable  */
  1422. int    lpos;
  1423.  
  1424. symbol    dosymb();
  1425. struct    libit    *getfnam();
  1426.  
  1427. /*
  1428.  *    Get hex characters, also allowing for 'k' and 'm'.
  1429.  */
  1430.  
  1431. int    ghex(str)
  1432. register  char    *str;
  1433. {
  1434.     register  int    result = 0;
  1435.     register  int    lt;
  1436.  
  1437.     for  (;;)  {
  1438.         lt = *str++;
  1439.         switch  (lt)  {
  1440.         default:
  1441. err:            (void) fprintf(stderr, "Invalid hex digit \'%c\'\n", lt);
  1442.             exit(1);
  1443.             
  1444.         case '\0':
  1445.             return    result;
  1446.             
  1447.         case '0':case '1':case '2':case '3':case '4':
  1448.         case '5':case '6':case '7':case '8':case '9':
  1449.             result = (result << 4) + lt - '0';
  1450.             continue;
  1451.             
  1452.         case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
  1453.             result = (result << 4) + lt - 'a' + 10;
  1454.             continue;
  1455.  
  1456.         case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
  1457.             result = (result << 4) + lt - 'A' + 10;
  1458.             continue;
  1459.         
  1460.         case 'k':case 'K':
  1461.             if  (*str != '\0')
  1462.                 goto  err;
  1463.             return  result << 10;
  1464.             
  1465.         case 'm':case 'M':
  1466.             if  (*str != '\0')
  1467.                 goto  err;
  1468.             return  result << 20;
  1469.         }
  1470.     }
  1471. }
  1472.  
  1473. /*
  1474.  *    Process entry line options.  Return number dealt with.
  1475.  */
  1476.  
  1477. int    doopts(av)
  1478. char    *av[];
  1479. {
  1480.     register  int    cnt = 0, lt;
  1481.     register  char    *arg;
  1482.     struct    var    vs;
  1483.     
  1484.     uvar(&vs);
  1485.     par_entry = vs.v_ustart;
  1486.     par_round = vs.v_txtrnd - 1;
  1487.     
  1488.     for  (;;)  {
  1489.         arg = *++av;
  1490.         if  (*arg++ != '-')
  1491.             return    cnt;
  1492.         cnt++;
  1493.         
  1494. nx:        switch  (lt = *arg++)  {
  1495.         default:
  1496.             (void) fprintf(stderr, "Bad option -%c\n", lt);
  1497.             exit(1);
  1498.             
  1499.         case  '\0':
  1500.             continue;
  1501.             
  1502.         case  'l':    /*  A file name  */
  1503.         case  'L':
  1504.             return    cnt - 1;
  1505.             
  1506.         case  's':
  1507.             lsyms++;
  1508.             goto  nx;
  1509.             
  1510.         case  'v':
  1511.             verbose++;
  1512.             goto  nx;
  1513.             
  1514.         case  'a':
  1515.             noabs++;
  1516.             goto  nx;
  1517.  
  1518.         case  'R':
  1519.         case  'N':
  1520.             if  (*arg == '\0')  {
  1521.                 cnt++;
  1522.                 arg = *++av;
  1523.                 if  (arg == NULL)  {
  1524. bo:                    (void) fprintf(stderr,"Bad -%c option\n",lt);
  1525.                     exit(1);
  1526.                 }
  1527.             }
  1528.             if  (lt == 'R')
  1529.                 par_entry = ghex(arg);
  1530.             else
  1531.                 par_round = ghex(arg) - 1;
  1532.             continue;
  1533.             
  1534.         case  't':
  1535.             if  (*arg == '\0')  {
  1536.                 cnt++;
  1537.                 arg = *++av;
  1538.                 if  (arg == NULL)
  1539.                     goto  bo;
  1540.             }
  1541.             tfnam = arg;
  1542.             continue;
  1543.             
  1544.         case  'o':
  1545.             if  (*arg == '\0')  {
  1546.                 cnt++;
  1547.                 arg = *++av;
  1548.                 if  (arg == NULL)
  1549.                     goto  bo;
  1550.             }
  1551.             if  (freopen(arg, "w", stdout) == NULL)  {
  1552.                 (void) fprintf(stderr, "Help! cant open %s\n", arg);
  1553.                 exit(20);
  1554.             }
  1555.             continue;
  1556.         }
  1557.     }
  1558. }
  1559.     
  1560. /*
  1561.  *    Open binary files.  Arrange to erase them when finished.
  1562.  */
  1563.  
  1564. void    bfopen(nam, fid)
  1565. char    *nam;
  1566. ef_fid    fid;
  1567. {
  1568.     char    fnam[80];
  1569.     
  1570.     (void) sprintf(fnam, "%s.tx", nam);
  1571.     if  ((fid->ef_t = open(fnam, O_RDWR|O_CREAT, 0666)) < 0)  {
  1572. efil:        (void) fprintf(stderr, "Help could not open %s\n", fnam);
  1573.         exit(4);
  1574.     }
  1575.     (void) unlink(fnam);
  1576.     (void) sprintf(fnam, "%s.dt", nam);
  1577.     if  ((fid->ef_d = open(fnam, O_RDWR|O_CREAT, 0666)) < 0)
  1578.         goto  efil;
  1579.     (void) unlink(fnam);
  1580. }
  1581.  
  1582. /*
  1583.  *    Close binary files.  They should get zapped anyway.
  1584.  */
  1585.  
  1586. void    bfclose(fid)
  1587. ef_fid    fid;
  1588. {
  1589.     (void) close(fid->ef_t);
  1590.     (void) close(fid->ef_d);
  1591. }
  1592.  
  1593. /*
  1594.  *    Main routine.
  1595.  */
  1596.  
  1597. main(argc, argv)
  1598. int    argc;
  1599. char    *argv[];
  1600. {
  1601.     int    i;
  1602.     char    *progname = argv[0];
  1603.     char    *msg;
  1604.     register  struct  libit  *lfd;
  1605.     
  1606.     i = doopts(argv);
  1607.     argc -= i;
  1608.     argv += i;
  1609.     
  1610.     if  (argc < 2)  {
  1611.         (void) fprintf(stderr, "Usage: %s [ options ] file\n", progname);
  1612.         exit(1);
  1613.     }
  1614.     
  1615.     lfd = getfnam(argv[1]);
  1616.     if  (lfd->lf_next > 0)  {
  1617.         (void) fprintf(stderr, "Main file (%s) cannot be library\n", argv[1]);
  1618.         exit(2);
  1619.     }
  1620.     
  1621.     bfopen(tfnam, &mainfile);
  1622.     if  (verbose)
  1623.         (void) fprintf(stderr, "Scanning text\n");
  1624.     if  (!rtext(lfd->lf_fd, lfd->lf_offset, &mainfile))  {
  1625.         msg = "text";
  1626. bf:        (void) fprintf(stderr, "Bad format input file - reading %s\n", msg);
  1627.         exit(5);
  1628.     }
  1629.     if  (verbose)
  1630.         (void) fprintf(stderr, "Scanning data\n");
  1631.     if  (!rdata(lfd->lf_fd, lfd->lf_offset, &mainfile))  {
  1632.         msg = "data";
  1633.         goto  bf;
  1634.     }
  1635.     if  (verbose)
  1636.         (void) fprintf(stderr, "Scanning symbols\n");
  1637.     if  (!rsymb(lfd->lf_fd, lfd->lf_offset, dosymb, &mainfile))  {
  1638.         msg = "symbols";
  1639.         goto  bf;
  1640.     }
  1641.     if  (verbose)
  1642.         (void) fprintf(stderr, "Scanning for relocation\n");
  1643.     if  ((rel = rrel(lfd->lf_fd, lfd->lf_offset, &mainfile)) < 0)  {
  1644.         msg = "reloc";
  1645.         goto  bf;
  1646.     }
  1647.     
  1648.     if  (rel)  {
  1649.         if  (verbose)
  1650.             (void) fprintf(stderr, "File is relocatable\n");
  1651.         if  (argc > 2)
  1652.             (void) fprintf(stderr, "Sorry - no scan on reloc files\n");
  1653.     }
  1654.     else
  1655.         lscan(argc - 2, &argv[2]);
  1656.  
  1657.     if  (verbose)
  1658.         (void) fprintf(stderr, "End of input\n");
  1659.     
  1660.     (void) close(lfd->lf_fd);
  1661.     if  (nmods > 0)
  1662.         (void) fprintf(stderr, "Warning: at least %d merged modules\n",
  1663.             nmods + 1);
  1664.  
  1665.     if  (mainfile.ef_stvec != NULL)  {
  1666.         free(mainfile.ef_stvec);
  1667.         mainfile.ef_stvec = NULL;
  1668.         mainfile.ef_stcnt = 0;
  1669.     }
  1670.     
  1671.     if  (verbose)
  1672.         (void) fprintf(stderr, "Text anal 1\n");
  1673.     intutext();
  1674.     if  (verbose)
  1675.         (void) fprintf(stderr, "Data anal 1\n");
  1676.     intudat(&mainfile);
  1677.     if  (!rel)  {
  1678.         if  (verbose)
  1679.             (void) fprintf(stderr, "Data anal 2\n");
  1680.         inturdat(&mainfile);
  1681.     }
  1682.     if  (lsyms)  {
  1683.         if  (verbose)
  1684.             (void) fprintf(stderr, "Local symbol scan\n");
  1685.         intlsym();
  1686.     }
  1687.     pabs();
  1688.     ptext(&mainfile);
  1689.     pdata(&mainfile);
  1690.     pbss(&mainfile);
  1691.     bfclose(&mainfile);
  1692.     exit(0);
  1693. }
  1694. SHAR_EOF
  1695. if test 6255 -ne "`wc -c < 'main.c'`"
  1696. then
  1697.     echo shar: error transmitting "'main.c'" '(should have been 6255 characters)'
  1698. fi
  1699. fi
  1700. echo shar: extracting "'prin.c'" '(5480 characters)'
  1701. if test -f 'prin.c'
  1702. then
  1703.     echo shar: will not over-write existing file "'prin.c'"
  1704. else
  1705. cat << \SHAR_EOF > 'prin.c'
  1706. /*
  1707.  *    SCCS:    @(#)prin.c    1.2    11/2/84    14:19:47
  1708.  *    Print stuff.
  1709.  *
  1710.  ***********************************************************************
  1711.  *    This software is copyright of
  1712.  *
  1713.  *        John M Collins
  1714.  *        47 Cedarwood Drive
  1715.  *        St Albans
  1716.  *        Herts, AL4 0DN
  1717.  *        England            +44 727 57267
  1718.  *
  1719.  *    and is released into the public domain on the following conditions:
  1720.  *
  1721.  *        1.  No free maintenance will be guaranteed.
  1722.  *        2.  Nothing may be based on this software without
  1723.  *            acknowledgement, including incorporation of this
  1724.  *            notice.
  1725.  *
  1726.  *    Notwithstanding the above, the author welcomes correspondence and bug
  1727.  *    fixes.
  1728.  ***********************************************************************
  1729.  */
  1730.  
  1731. #include <stdio.h>
  1732. #include <a.out.h>
  1733. #include "unc.h"
  1734.  
  1735. #define    LINELNG    70
  1736.  
  1737. void    gette(), getde();
  1738. long    gettw(), getdw();
  1739. void    prinst();
  1740.  
  1741. char    noabs;            /*  No non-global absolutes  */
  1742. int    rel;            /*  File being analysed is relocatable  */
  1743. int    lpos;
  1744.  
  1745. struct    commit    abstab, comtab;
  1746.  
  1747. /*
  1748.  *    Print absolute and common values.
  1749.  */
  1750.  
  1751. void    pabs()
  1752. {
  1753.     register  int    i;
  1754.     register  symbol  cs;
  1755.  
  1756.     for  (i = 0;  i < abstab.c_int;  i++)
  1757.     
  1758.     for  (i = 0;  i < abstab.c_int;  i++)  {
  1759.         cs = abstab.c_symb[i];
  1760.         if  (cs->s_glob)
  1761.             (void) printf("\t.globl\t%s\n", cs->s_name);
  1762.         else  if  (noabs)
  1763.             continue;
  1764.         (void) printf("%s\t=\t0x%lx\n", cs->s_name, cs->s_value);
  1765.     }
  1766.     for  (i = 0;  i < comtab.c_int;  i++)  {
  1767.         cs = comtab.c_symb[i];
  1768.         (void) printf("\t.comm\t%s,%d\n", cs->s_name, cs->s_value);
  1769.     }
  1770. }
  1771.  
  1772. /*
  1773.  *    Print out labels.
  1774.  */
  1775.  
  1776. void    plabs(ls, seg)
  1777. register  symbol  ls;
  1778. int    seg;
  1779. {
  1780.     for  (; ls != NULL;  ls = ls->s_link)  {
  1781.         if  (ls->s_type != seg)
  1782.             continue;
  1783.         if  (ls->s_lsymb)  {
  1784.             (void) printf("%u$:\n", ls->s_lsymb);
  1785.             return;        /*  Set last  */
  1786.         }
  1787.         if  (ls->s_glob)
  1788.             (void) printf("\n\t.globl\t%s", ls->s_name);
  1789.         (void) printf("\n%s:\n", ls->s_name);
  1790.     }
  1791. }
  1792.  
  1793. /*
  1794.  *    Print out text.
  1795.  */
  1796.  
  1797. void    ptext(fid)
  1798. register  ef_fid  fid;
  1799. {
  1800.     register  long    tpos, endt;
  1801.     t_entry    tstr;
  1802.  
  1803.     (void) printf(".text\n");
  1804.     
  1805.     tpos = fid->ef_tbase;
  1806.     endt = tpos + fid->ef_tsize;
  1807. contin:    
  1808.     for  (;  tpos < endt;  tpos += tstr.t_lng * 2)  {
  1809.         gette(fid, tpos, &tstr);
  1810.         plabs(tstr.t_lab, TEXT);
  1811.         if  (tstr.t_type == T_BEGIN)
  1812.             prinst(&tstr, tpos);
  1813.         else  if  (tstr.t_relsymb != NULL)  {
  1814.             (void) printf("\t.long\t%s", tstr.t_relsymb->s_name);
  1815.             if  (tstr.t_relsymb->s_type!=TEXT &&
  1816.                 tstr.t_relsymb->s_type!=DATA)
  1817.                 (void) printf("+0x%x", gettw(fid, tpos, R_LONG));
  1818.             putchar('\n');
  1819.             tpos += 4;
  1820.             goto  contin;
  1821.         }
  1822.         else
  1823.             (void) printf("\t.word\t0x%x\n", tstr.t_contents);
  1824.     }
  1825.  
  1826.     /*
  1827.      *    Print out any trailing label.
  1828.      */
  1829.     
  1830.     gette(fid, tpos, &tstr);
  1831.     plabs(tstr.t_lab, TEXT);
  1832. }
  1833.  
  1834. /*
  1835.  *    Print out data.
  1836.  */
  1837.  
  1838. void    pdata(fid)
  1839. register  ef_fid  fid;
  1840. {
  1841.     register  long    dpos, endd;
  1842.     register  int    lng;
  1843.     unsigned  ctyp;
  1844.     int    had, par, inc;
  1845.     char    *msg;
  1846.     d_entry    dstr;
  1847.     
  1848.     (void) printf("\n.data\n");
  1849.     
  1850.     dpos = fid->ef_dbase;
  1851.     endd = dpos + fid->ef_dsize;
  1852.  
  1853.     while  (dpos < endd)  {
  1854.         
  1855.         getde(fid, dpos, &dstr);
  1856.         plabs(dstr.d_lab, DATA);
  1857.             
  1858.         switch  (dstr.d_type)  {
  1859.         case  D_CONT:
  1860.             (void) fprintf(stderr, "Data sync error\n");
  1861.             exit(200);
  1862.             
  1863.         case  D_ASC:
  1864.         case  D_ASCZ:
  1865.             ctyp = dstr.d_type;
  1866.             lng = dstr.d_lng;
  1867.             (void) printf("\t.asci");
  1868.             if  (ctyp == D_ASC)
  1869.                 (void) printf("i\t\"");
  1870.             else  {
  1871.                 (void) printf("z\t\"");
  1872.                 lng--;
  1873.             }
  1874.                 
  1875.             while  (lng > 0)  {
  1876.                 getde(fid, dpos, &dstr);
  1877.                 switch  (dstr.d_contents)  {
  1878.                 default:
  1879.                     if  (dstr.d_contents < ' ' ||
  1880.                         dstr.d_contents > '~')
  1881.                         (void) printf("\\%.3o", dstr.d_contents);
  1882.                     else
  1883.                         putchar(dstr.d_contents);
  1884.                     break;
  1885.                 case  '\"':
  1886.                 case  '\'':
  1887.                 case  '\\':
  1888.                 case  '|':
  1889.                     (void) printf("\\%c", dstr.d_contents);
  1890.                     break;
  1891.                 case  '\b':
  1892.                     (void) printf("\\b");
  1893.                     break;
  1894.                 case  '\n':
  1895.                     (void) printf("\\n");
  1896.                     break;
  1897.                 case  '\r':
  1898.                     (void) printf("\\r");
  1899.                     break;
  1900.                 }
  1901.                 
  1902.                 lng--;
  1903.                 dpos++;
  1904.             }
  1905.             (void) printf("\"\n");
  1906.             if  (ctyp == D_ASCZ)
  1907.                 dpos++;
  1908.             break;
  1909.  
  1910.         case  D_BYTE:
  1911.             msg = "byte";
  1912.             par = R_BYTE;
  1913.             inc = 1;
  1914.             goto  wrest;
  1915.             
  1916.         case  D_WORD:
  1917.             msg = "word";
  1918.             par = R_WORD;
  1919.             inc = 2;
  1920.             goto  wrest;
  1921.             
  1922.         case  D_LONG:
  1923.             msg = "long";
  1924.             par = R_LONG;
  1925.             inc = 4;
  1926.         wrest:
  1927.             (void) printf("\t.%s\t", msg);
  1928.             lng = dstr.d_lng;
  1929.             lpos = 16;
  1930.             had = 0;
  1931.             while  (lng > 0)  {
  1932.                 if  (lpos > LINELNG)  {
  1933.                     (void) printf("\n\t.%s\t", msg);
  1934.                     lpos = 16;
  1935.                 }
  1936.                 else  if  (had)
  1937.                     lpos += printf(", ");
  1938.  
  1939.                 lpos += printf("0x%x", getdw(fid, dpos, par));
  1940.                 lng -= inc;
  1941.                 dpos += inc;
  1942.                 had++;
  1943.             }
  1944.             putchar('\n');
  1945.             break;
  1946.  
  1947.         case  D_ADDR:
  1948.             (void) printf("\t.long\t");
  1949.             lng = dstr.d_lng;
  1950.             lpos = 16;
  1951.             had = 0;
  1952.             while  (lng > 0)  {
  1953.                 if  (lpos > LINELNG)  {
  1954.                     (void) printf("\n\t.long\t");
  1955.                     lpos = 16;
  1956.                 }
  1957.                 else  if  (had)
  1958.                     lpos += printf(", ");
  1959.  
  1960.                 getde(fid, dpos, &dstr);
  1961.                 lpos += printf("%s", dstr.d_relsymb->s_name);
  1962.                 lng -= sizeof(long);
  1963.                 dpos += sizeof(long);
  1964.                 had++;
  1965.             }
  1966.             putchar('\n');
  1967.             break;
  1968.         }
  1969.     }
  1970.     
  1971.     /*
  1972.      *    Print trailing label.
  1973.      */
  1974.     
  1975.     getde(fid, dpos, &dstr);
  1976.     plabs(dstr.d_lab, DATA);
  1977. }
  1978.  
  1979. void    pbss(fid)
  1980. register  ef_fid  fid;
  1981. {
  1982.     register  long    bpos = fid->ef_bbase;
  1983.     long    endb = fid->ef_end;
  1984.     d_entry    bstr;
  1985.     
  1986.     (void) printf("\n.bss\n");
  1987.     
  1988.     while  (bpos < endb)  {
  1989.         getde(fid, bpos, &bstr);
  1990.         plabs(bstr.d_lab, BSS);
  1991.         (void) printf("\t.space\t%d\n", bstr.d_lng);
  1992.         bpos += bstr.d_lng;
  1993.     }
  1994.     
  1995.     getde(fid, endb, &bstr);
  1996.     plabs(bstr.d_lab, BSS);
  1997. }
  1998. SHAR_EOF
  1999. if test 5480 -ne "`wc -c < 'prin.c'`"
  2000. then
  2001.     echo shar: error transmitting "'prin.c'" '(should have been 5480 characters)'
  2002. fi
  2003. fi
  2004. echo shar: extracting "'robj.c'" '(18429 characters)'
  2005. if test -f 'robj.c'
  2006. then
  2007.     echo shar: will not over-write existing file "'robj.c'"
  2008. else
  2009. cat << \SHAR_EOF > 'robj.c'
  2010. /*
  2011.  *    SCCS:    @(#)robj.c    1.2    11/2/84    14:19:59
  2012.  *    Read object files.
  2013.  *
  2014.  ***********************************************************************
  2015.  *    This software is copyright of
  2016.  *
  2017.  *        John M Collins
  2018.  *        47 Cedarwood Drive
  2019.  *        St Albans
  2020.  *        Herts, AL4 0DN
  2021.  *        England            +44 727 57267
  2022.  *
  2023.  *    and is released into the public domain on the following conditions:
  2024.  *
  2025.  *        1.  No free maintenance will be guaranteed.
  2026.  *        2.  Nothing may be based on this software without
  2027.  *            acknowledgement, including incorporation of this
  2028.  *            notice.
  2029.  *
  2030.  *    Notwithstanding the above, the author welcomes correspondence and bug
  2031.  *    fixes.
  2032.  ***********************************************************************
  2033.  *
  2034.  *    This particular module will obviously have to be munged beyond
  2035.  *    recognition for another object format.
  2036.  */
  2037.  
  2038. #include <stdio.h>
  2039. #include <a.out.h>
  2040. #include "unc.h"
  2041.  
  2042. void    gette(), getde(), setde(), putte(), putde();
  2043. long    gettw(), getdw();
  2044. void    reallst(), lclash(), nomem(), unimpl();
  2045. void    addit();
  2046. char    *malloc();
  2047. long    lseek();
  2048.  
  2049. int    par_entry, par_round, nmods, donedrel, donebrel;
  2050. struct    commit    abstab, comtab, dreltab;
  2051. long    trelpos, drelpos, brelpos;
  2052.  
  2053. ef_fids    mainfile;
  2054.  
  2055. symbol    lookup(), inventsymb(), getnsymb();
  2056.  
  2057. #define    DBSIZE    100
  2058. #define    STINIT    20
  2059.  
  2060. /*
  2061.  *    Read text segment.  Return 0 if not ok.
  2062.  */
  2063.  
  2064. int    rtext(inf, offset, outf)
  2065. int    inf;        /*  a.out file (possibly in library)  */
  2066. long    offset;        /*  Offset from start of inf of a.out file  */
  2067. ef_fid    outf;        /*  Output file descriptor  */
  2068. {
  2069.     t_entry        tstr;
  2070.     struct    bhdr    filhdr;
  2071.     register  long    size;
  2072.     register  int    i, l;
  2073.     unsigned  short    inbuf[DBSIZE/2];
  2074.  
  2075.     /*
  2076.      *    Initialise fields in structure.
  2077.      */
  2078.     
  2079.     tstr.t_type = T_UNKNOWN;
  2080.     tstr.t_vins = 1;        /*  For the moment  */
  2081.     tstr.t_bdest = 0;
  2082.     tstr.t_gbdest = 0;
  2083.     tstr.t_lng = 1;
  2084.     tstr.t_reloc = R_NONE;
  2085.     tstr.t_rdisp = 0;
  2086.     tstr.t_isrel = 0;
  2087.     tstr.t_amap = 0;
  2088.     tstr.t_dref = 0;
  2089.     tstr.t_relsymb = NULL;
  2090.     tstr.t_reldisp = 0;
  2091.     tstr.t_lab = NULL;
  2092.     tstr.t_lsymb = 0;
  2093.     tstr.t_refhi = 0;
  2094.     tstr.t_reflo = 0x7fffffff;
  2095.     tstr.t_match = 0;
  2096.     
  2097.     /*
  2098.      *    Read a.out header.
  2099.      */
  2100.     
  2101.     (void) lseek(inf, offset, 0);
  2102.  
  2103.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  2104.         return    0;
  2105.  
  2106.     if  (filhdr.fmagic != FMAGIC  &&  filhdr.fmagic != NMAGIC)
  2107.         return    0;
  2108.  
  2109.     /*
  2110.      *    Warn user if entry point does not tie up.
  2111.      */
  2112.     
  2113.     if  (filhdr.entry != par_entry)
  2114.         (void) fprintf(stderr, "Warning: File has -R%X\n", filhdr.entry);
  2115.  
  2116.     outf->ef_entry = filhdr.entry;
  2117.     outf->ef_tbase = filhdr.entry;
  2118.     outf->ef_dbase = filhdr.tsize + filhdr.entry;
  2119.  
  2120.     if  (filhdr.fmagic == NMAGIC)
  2121.         outf->ef_dbase = (outf->ef_dbase + par_round) & (~par_round);
  2122.  
  2123.     outf->ef_bbase = outf->ef_dbase + filhdr.dsize;
  2124.     outf->ef_end = outf->ef_bbase + filhdr.bsize;
  2125.  
  2126.     outf->ef_tsize = filhdr.tsize;
  2127.     outf->ef_dsize = filhdr.dsize;
  2128.     outf->ef_bsize = filhdr.bsize;
  2129.     
  2130.     (void) lseek(inf, offset + TEXTPOS, 0);
  2131.     
  2132.     size = outf->ef_tsize;
  2133.     
  2134.     while  (size > 1)  {
  2135.         l = size > DBSIZE? DBSIZE: size;
  2136.         if  (read(inf, (char *)inbuf, l) != l)
  2137.             return    0;
  2138.         l /= 2;
  2139.         for  (i = 0;  i < l;  i++)  {
  2140.             tstr.t_contents = inbuf[i];
  2141.             (void) write(outf->ef_t, (char *)&tstr, sizeof(tstr));
  2142.         }
  2143.         size -= l + l;
  2144.     }
  2145.     
  2146.     /*
  2147.      *    Extra one to cope with "etext".
  2148.      */
  2149.     
  2150.     (void) write(outf->ef_t, (char *)&tstr, sizeof(tstr));
  2151.     return    1;
  2152. }
  2153.  
  2154. /*
  2155.  *    Same sort of thing for the data segment.
  2156.  */
  2157.  
  2158. int    rdata(inf, offset, outf)
  2159. int    inf;        /*  a.out file (possibly in library)  */
  2160. long    offset;        /*  Offset from start of inf of a.out file  */
  2161. ef_fid    outf;        /*  Output file descriptor  */
  2162. {
  2163.     d_entry        dstr;
  2164.     struct    bhdr    filhdr;
  2165.     register  long    size;
  2166.     register  int    i, l;
  2167.     unsigned  char    inbuf[DBSIZE];
  2168.  
  2169.     /*
  2170.      *    Initialise fields in structure.
  2171.      */
  2172.     
  2173.     dstr.d_type = D_BYTE;
  2174.     dstr.d_reloc = R_NONE;
  2175.     dstr.d_lng = 1;
  2176.     dstr.d_relsymb = NULL;
  2177.     dstr.d_reldisp = 0;
  2178.     dstr.d_lab = NULL;
  2179.     
  2180.     /*
  2181.      *    Read a.out header.
  2182.      */
  2183.     
  2184.     (void) lseek(inf, offset, 0);
  2185.  
  2186.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  2187.         return    0;
  2188.  
  2189.     (void) lseek(inf, offset + DATAPOS, 0);
  2190.     
  2191.     size = outf->ef_dsize;
  2192.     
  2193.     while  (size > 0)  {
  2194.         l = size > DBSIZE? DBSIZE: size;
  2195.         if  (read(inf, (char *)inbuf, l) != l)
  2196.             return    0;
  2197.         for  (i = 0;  i < l;  i++)  {
  2198.             dstr.d_contents = inbuf[i];
  2199.             (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
  2200.         }
  2201.         size -= l;
  2202.     }
  2203.     
  2204.     /*
  2205.      *    Repeat for BSS segment.
  2206.      */
  2207.  
  2208.     dstr.d_contents = 0;
  2209.     for  (size = outf->ef_bsize;  size > 0;  size--)
  2210.         (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
  2211.     
  2212.     /*
  2213.      *    Extra one to cope with "end".
  2214.      */
  2215.     
  2216.     (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
  2217.     return    1;
  2218. }
  2219.  
  2220. /*
  2221.  *    Process symbol table segment.
  2222.  */
  2223.  
  2224. int    rsymb(inf, offset, dproc, outf)
  2225. int    inf;        /*  a.out file (possibly in library)  */
  2226. long    offset;        /*  Offset from start of inf of a.out file  */
  2227. symbol    (*dproc)();
  2228. register  ef_fid  outf;    /*  Output file descriptor  */
  2229. {
  2230.     register  symbol  csym;
  2231.     struct    bhdr    filhdr;
  2232.     struct    sym    isym;
  2233.     register  long    size;
  2234.     register  int    i, l;
  2235.     char    inbuf[SYMLENGTH+1];
  2236.  
  2237.     /*
  2238.      *    Read a.out header.
  2239.      */
  2240.     
  2241.     (void) lseek(inf, offset, 0);
  2242.  
  2243.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  2244.         return    0;
  2245.  
  2246.     offset += SYMPOS;
  2247.     size = filhdr.ssize;
  2248.     if  (size <= 0)
  2249.         return    1;
  2250.  
  2251.     /*
  2252.      *    Guesstimate symbol table vector size.
  2253.      */
  2254.  
  2255.     l = size / (sizeof(struct sym) + 4);
  2256.     if  (l <= 0)
  2257.         l = STINIT;
  2258.  
  2259.     outf->ef_stvec = (symbol *) malloc(l * sizeof(symbol));
  2260.     if  (outf->ef_stvec == NULL)
  2261.         nomem();
  2262.  
  2263.     outf->ef_stcnt = 0;
  2264.     outf->ef_stmax = l;
  2265.     
  2266.     while  (size > sizeof(struct sym))  {
  2267.         (void) lseek(inf, offset, 0);
  2268.         if  (read(inf, (char *)&isym, sizeof(isym)) != sizeof(isym))
  2269.             return    0;
  2270.         size -= sizeof(isym);
  2271.         l = SYMLENGTH;
  2272.         if  (l > size)
  2273.             l = size;
  2274.         if  (read(inf, inbuf, l) != l)
  2275.             return    0;
  2276.         inbuf[l] = '\0';
  2277.         for  (i = 0; inbuf[i] != '\0';  i++)
  2278.             ;
  2279.         size -= i + 1;
  2280.         offset += sizeof(isym) + i + 1;
  2281.         csym = (*dproc)(lookup(inbuf), isym.stype, isym.svalue, outf);
  2282.         if  (outf->ef_stcnt >= outf->ef_stmax)
  2283.             reallst(outf);
  2284.         outf->ef_stvec[outf->ef_stcnt++] = csym;
  2285.     }
  2286.     return    1;
  2287. }
  2288.  
  2289. /*
  2290.  *    Process relocation stuff.  -1 error, 0 no relocation, 1 relocation.
  2291.  */
  2292.  
  2293. int    rrel(inf, offset, outf)
  2294. int    inf;        /*  a.out file (possibly in library)  */
  2295. long    offset;        /*  Offset from start of inf of a.out file  */
  2296. ef_fid    outf;        /*  Output file descriptor  */
  2297. {
  2298.     struct    bhdr    filhdr;
  2299.     struct    reloc    crel;
  2300.     t_entry    tstr;
  2301.     d_entry    dstr;
  2302.     register  long    size;
  2303.     long    cont, pos;
  2304.  
  2305.     /*
  2306.      *    Read a.out header.
  2307.      */
  2308.     
  2309.     (void) lseek(inf, offset, 0);
  2310.  
  2311.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  2312.         return    -1;
  2313.     if  (filhdr.rtsize <= 0  &&  filhdr.rdsize <= 0)
  2314.         return    0;
  2315.  
  2316.     size  =  filhdr.rtsize;
  2317.  
  2318.     (void) lseek(inf, RTEXTPOS + offset, 0);
  2319.     while  (size >= sizeof(struct reloc))  {
  2320.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  2321.             return    -1;
  2322.  
  2323.         pos = crel.rpos + outf->ef_tbase;
  2324.         gette(outf, pos, &tstr);
  2325.         tstr.t_reloc = crel.rsize + 1;    /*  Fiddle!  YUK!!!  */
  2326.         tstr.t_rdisp = crel.rdisp;
  2327.         tstr.t_rptr = crel.rsegment;
  2328.         if  (crel.rsegment == REXT)  {
  2329.             if  (crel.rsymbol >= outf->ef_stcnt)
  2330.                 return  -1;
  2331.             tstr.t_relsymb = outf->ef_stvec[crel.rsymbol];
  2332.             tstr.t_reldisp = gettw(outf, pos, (int)crel.rsize+1);
  2333.         }
  2334.         else  {
  2335.             cont = gettw(outf, pos, (int)crel.rsize+1);
  2336.             tstr.t_relsymb = getnsymb(outf, crel.rsegment, cont);
  2337.         }
  2338.         tstr.t_relsymb->s_used++;
  2339.         putte(outf, pos, &tstr);
  2340.         size -= sizeof(crel);
  2341.     }
  2342.     
  2343.     /*
  2344.      *    And now repeat all that for data relocations.
  2345.      */
  2346.     
  2347.     size  =  filhdr.rdsize;
  2348.     
  2349.     (void) lseek(inf, RDATAPOS + offset, 0);
  2350.     while  (size >= sizeof(struct reloc))  {
  2351.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  2352.             return    -1;
  2353.  
  2354.         pos = crel.rpos + outf->ef_dbase;
  2355.         getde(outf, pos, &dstr);
  2356.         dstr.d_reloc = crel.rsize + 1;    /*  Fiddle!  YUK!!!  */
  2357.         dstr.d_rptr = crel.rsegment;
  2358.  
  2359.         if  (crel.rsegment == REXT)  {
  2360.             if  (crel.rsymbol >= outf->ef_stcnt)
  2361.                 return  -1;
  2362.             dstr.d_relsymb = outf->ef_stvec[crel.rsymbol];
  2363.             dstr.d_reldisp = getdw(outf, pos, (int)crel.rsize+1);
  2364.         }
  2365.         else  {
  2366.             cont = getdw(outf, pos, (int)crel.rsize+1);
  2367.             dstr.d_relsymb = getnsymb(outf, crel.rsegment, cont);
  2368.             if  (dstr.d_relsymb->s_type == TEXT)  {
  2369.                 gette(outf, cont, &tstr);
  2370.                 tstr.t_dref = 1;
  2371.                 putte(outf, cont, &tstr);
  2372.             }
  2373.         }
  2374.         switch  (crel.rsize)  {
  2375.         default:
  2376.             unimpl("Data byte relocation");
  2377.             break;
  2378.         case  RWORD:
  2379.             unimpl("data word reloc");
  2380.             dstr.d_type = D_WORD;
  2381.             dstr.d_lng = 2;
  2382.             setde(outf, pos+1, D_CONT, 1);
  2383.             break;
  2384.         case  RLONG:
  2385.             dstr.d_type = D_ADDR;
  2386.             dstr.d_lng = 4;
  2387.             setde(outf, pos+1, D_CONT, 1);
  2388.             setde(outf, pos+2, D_CONT, 1);
  2389.             setde(outf, pos+3, D_CONT, 1);
  2390.             break;
  2391.         }
  2392.         dstr.d_relsymb->s_used++;
  2393.         putde(outf, pos, &dstr);
  2394.         size -= sizeof(crel);
  2395.     }
  2396.     return 1;
  2397. }
  2398.  
  2399. /*
  2400.  *    Process a symbol.
  2401.  */
  2402.  
  2403. symbol    dosymb(sy, type, val, fid)
  2404. register  symbol  sy;
  2405. int    type;
  2406. long    val;
  2407. ef_fid    fid;
  2408. {
  2409.     t_entry    tstr;
  2410.     d_entry    dstr;
  2411.     
  2412.     if  (!sy->s_newsym)  {
  2413.         if  (type & EXTERN)  {
  2414.             (void) fprintf(stderr, "Duplicate symbol %s\n", sy->s_name);
  2415.             exit(10);
  2416.         }
  2417.         if  (++sy->s_defs > nmods)
  2418.             nmods = sy->s_defs;
  2419.         sy = inventsymb("DUP");
  2420.     }
  2421.  
  2422.     sy->s_value = val;
  2423.     
  2424.     switch  (type)  {
  2425.     default:
  2426.         return    NULL;
  2427.         
  2428.     case  EXTERN|UNDEF:
  2429.         if  (val != 0)  {
  2430.             sy->s_type = COMM;
  2431.             addit(&comtab, sy);
  2432.         }
  2433.         else
  2434.             sy->s_type = N_UNDF;
  2435.         sy->s_glob = 1;
  2436.         break;
  2437.         
  2438.     case  EXTERN|ABS:
  2439.         sy->s_type = N_ABS;
  2440.         sy->s_glob = 1;
  2441.         addit(&abstab, sy);
  2442.         break;
  2443.         
  2444.     case  ABS:
  2445.         sy->s_type = N_ABS;
  2446.         addit(&abstab, sy);
  2447.         break;
  2448.         
  2449.     case  EXTERN|TEXT:
  2450.     case  TEXT:
  2451.         sy->s_type = N_TEXT;
  2452.         gette(fid, val, &tstr);
  2453.         tstr.t_bdest = 1;
  2454.         if  (type & EXTERN)  {
  2455.             tstr.t_gbdest = 1;
  2456.             sy->s_glob = 1;
  2457.         }
  2458.         sy->s_link = tstr.t_lab;
  2459.         tstr.t_lab = sy;
  2460.         putte(fid, val, &tstr);
  2461.         break;
  2462.         
  2463.     case  BSS:
  2464.     case  EXTERN|BSS:
  2465.         sy->s_type = N_BSS;
  2466.         goto    datrest;
  2467.     case  DATA:
  2468.     case  EXTERN|DATA:
  2469.         sy->s_type = N_DATA;
  2470.     datrest:
  2471.         getde(fid, val, &dstr);
  2472.         if  (type & EXTERN)
  2473.             sy->s_glob = 1;
  2474.         sy->s_link = dstr.d_lab;
  2475.         dstr.d_lab = sy;
  2476.         putde(fid, val, &dstr);
  2477.         break;
  2478.     }
  2479.     
  2480.     sy->s_newsym = 0;
  2481.     return    sy;
  2482. }
  2483.  
  2484. /*
  2485.  *    Process relocation stuff in putative library modules.
  2486.  *    The main function of all this is to mark which bits of the text
  2487.  *    not to look at as I compare the stuff.
  2488.  *
  2489.  *    As with "rrel", return -1 error, 0 no relocation, 1 relocation.
  2490.  */
  2491.  
  2492. int    rrell1(inf, offset, outf)
  2493. int    inf;        /*  a.out file (possibly in library)  */
  2494. long    offset;        /*  Offset from start of inf of a.out file  */
  2495. ef_fid    outf;        /*  Output file descriptor  */
  2496. {
  2497.     struct    bhdr    filhdr;
  2498.     struct    reloc    crel;
  2499.     t_entry    tstr;
  2500.     register  long    size;
  2501.     long    pos;
  2502.  
  2503.     /*
  2504.      *    Read a.out header.
  2505.      */
  2506.     
  2507.     (void) lseek(inf, offset, 0);
  2508.  
  2509.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  2510.         return    -1;
  2511.     if  (filhdr.rtsize <= 0  &&  filhdr.rdsize <= 0)
  2512.         return    0;
  2513.  
  2514.     size  =  filhdr.rtsize;
  2515.  
  2516.     (void) lseek(inf, RTEXTPOS + offset, 0);
  2517.     while  (size >= sizeof(struct reloc))  {
  2518.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  2519.             return    -1;
  2520.  
  2521.         pos = crel.rpos + outf->ef_tbase;
  2522.         gette(outf, pos, &tstr);
  2523.         tstr.t_reloc = crel.rsize + 1;    /*  Fiddle!  YUK!!!  */
  2524.         tstr.t_rdisp = crel.rdisp;
  2525.         tstr.t_rptr = crel.rsegment;
  2526.         tstr.t_isrel = 1;
  2527.         putte(outf, pos, &tstr);
  2528.         if  (crel.rsize == RLONG)  {
  2529.             gette(outf, pos+2, &tstr);
  2530.             tstr.t_isrel = 1;
  2531.             putte(outf, pos+2, &tstr);
  2532.         }
  2533.         size -= sizeof(crel);
  2534.     }
  2535.     
  2536.     /*
  2537.      *    Dont bother with data relocation at this stage. We'll
  2538.      *    tie that up later.
  2539.      */
  2540.     
  2541.     return 1;
  2542. }
  2543.  
  2544. /*
  2545.  *    Process a symbol in library file.  The extern variable trelpos gives
  2546.  *    the place in the main file where the library module is relocated.
  2547.  *    We don't know the data position until we do the final merge, perhaps
  2548.  *    not even then.
  2549.  */
  2550.  
  2551. symbol    dolsymb(sy, type, val, fid)
  2552. register  symbol  sy;
  2553. int    type;
  2554. long    val;
  2555. ef_fid    fid;
  2556. {
  2557.     t_entry    tstr;
  2558.     
  2559.     switch  (type)  {
  2560.     default:
  2561.         return    NULL;
  2562.         
  2563.     case  EXTERN|UNDEF:
  2564.         if  (!sy->s_newsym)
  2565.             return    sy;
  2566.         sy->s_value = val;
  2567.         if  (val != 0)  {
  2568.             sy->s_type = COMM;
  2569.             addit(&dreltab, sy);
  2570.         }
  2571.         else
  2572.             sy->s_type = N_UNDF;
  2573.         sy->s_glob = 1;
  2574.         break;
  2575.         
  2576.     case  EXTERN|ABS:
  2577.         if  (!sy->s_newsym)  {
  2578.             if  (sy->s_type != N_ABS || sy->s_value != val)
  2579.                 lclash("abs");
  2580.         }
  2581.         sy->s_type = N_ABS;
  2582.         sy->s_value = val;
  2583.         sy->s_glob = 1;
  2584.         addit(&abstab, sy);
  2585.         break;
  2586.         
  2587.     case  EXTERN|TEXT:
  2588.         sy->s_type = N_TEXT;
  2589.         val += trelpos - fid->ef_tbase;
  2590.         if  (!sy->s_newsym)  {
  2591.             if  (val != sy->s_value)
  2592.                 lclash("tsym");
  2593.             return    sy;
  2594.         }
  2595.         sy->s_value = val;
  2596.         gette(&mainfile, val, &tstr);
  2597.         tstr.t_bdest = 1;
  2598.         tstr.t_gbdest = 1;
  2599.         sy->s_glob = 1;
  2600.         sy->s_link = tstr.t_lab;
  2601.         tstr.t_lab = sy;
  2602.         putte(&mainfile, val, &tstr);
  2603.         break;
  2604.  
  2605.     case  EXTERN|BSS:
  2606.         if  (!sy->s_newsym)
  2607.             return    sy;
  2608.         sy->s_type = N_BSS;
  2609.         sy->s_value = val - fid->ef_bbase;
  2610.         goto    datrest;
  2611.  
  2612.     case  EXTERN|DATA:
  2613.         if  (!sy->s_newsym)
  2614.             return    sy;
  2615.         sy->s_type = N_DATA;
  2616.         sy->s_value = val - fid->ef_dbase;
  2617.     datrest:
  2618.         sy->s_glob = 1;
  2619.         addit(&dreltab, sy);
  2620.         break;
  2621.     }
  2622.     
  2623.     sy->s_newsym = 0;
  2624.     return    sy;
  2625. }
  2626.  
  2627. /*
  2628.  *    Change definition of undefined symbol as we define it.
  2629.  */
  2630.  
  2631. void    reassign(sy, val)
  2632. register  symbol  sy;
  2633. long    val;
  2634. {
  2635.     sy->s_value = val;
  2636.  
  2637.     if  (val < mainfile.ef_tbase)  {
  2638.         sy->s_type = N_ABS;
  2639.         addit(&abstab, sy);
  2640.     }
  2641.     else  if  (val < mainfile.ef_dbase)  {
  2642.         t_entry    tstr;
  2643.         
  2644.         sy->s_type = N_TEXT;
  2645.         gette(&mainfile, val, &tstr);
  2646.         tstr.t_bdest = 1;
  2647.         tstr.t_gbdest = 1;
  2648.         sy->s_glob = 1;
  2649.         sy->s_link = tstr.t_lab;
  2650.         tstr.t_lab = sy;
  2651.         putte(&mainfile, val, &tstr);
  2652.     }
  2653.     else  {
  2654.         d_entry dstr;
  2655.         
  2656.         sy->s_type = val < mainfile.ef_bbase? N_DATA: N_BSS;
  2657.         getde(&mainfile, val, &dstr);
  2658.         sy->s_link = dstr.d_lab;
  2659.         dstr.d_lab = sy;
  2660.         putde(&mainfile, val, &dstr);
  2661.     }
  2662. }
  2663.  
  2664. /*
  2665.  *    When we discover where bss or data come, reallocate the table.
  2666.  */
  2667.  
  2668. void    zapdat(seg, inc)
  2669. int    seg;
  2670. long    inc;
  2671. {
  2672.     register  int    i;
  2673.     register  symbol  csymb;
  2674.     d_entry    dent;
  2675.     
  2676.     for  (i = 0;  i < dreltab.c_int;  i++) {
  2677.         csymb = dreltab.c_symb[i];
  2678.         if  (csymb->s_type != seg)
  2679.             continue;
  2680.         csymb->s_value += inc;
  2681.         getde(&mainfile, csymb->s_value, &dent);
  2682.         csymb->s_link = dent.d_lab;
  2683.         dent.d_lab = csymb;
  2684.         putde(&mainfile, csymb->s_value, &dent);
  2685.     }
  2686. }
  2687.  
  2688. /*
  2689.  *    Process relocation stuff in library module which we are inserting.
  2690.  *    Horrors if something goes wrong.
  2691.  */
  2692.  
  2693. void    rrell2(inf, offset, outf)
  2694. int    inf;        /*  a.out file (possibly in library)  */
  2695. long    offset;        /*  Offset from start of inf of a.out file  */
  2696. ef_fid    outf;        /*  Output file descriptor  */
  2697. {
  2698.     struct    bhdr    filhdr;
  2699.     struct    reloc    crel;
  2700.     t_entry    mtstr;
  2701.     d_entry    mdstr;
  2702.     register  long    size;
  2703.     register  symbol  csymb;
  2704.     long    pos, mpos, mval, lval;
  2705.     int    dhere = 0;        /*  Mark whether bss done  */
  2706.  
  2707.     /*
  2708.      *    Read a.out header.
  2709.      */
  2710.     
  2711.     (void) lseek(inf, offset, 0);
  2712.  
  2713.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  2714.         return;
  2715.     if  (filhdr.rtsize <= 0  &&  filhdr.rdsize <= 0)
  2716.         return;
  2717.  
  2718.     size  =  filhdr.rtsize;
  2719.  
  2720.     (void) lseek(inf, RTEXTPOS + offset, 0);
  2721.     for  (;  size >= sizeof(struct reloc);  size -= sizeof(crel))  {
  2722.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  2723.             lclash("rd trel");
  2724.  
  2725.         pos = crel.rpos + outf->ef_tbase;
  2726.         mpos = crel.rpos + trelpos;
  2727.         gette(&mainfile, mpos, &mtstr);
  2728.         lval = gettw(outf, pos, (int)crel.rsize+1);
  2729.         mval = gettw(&mainfile, mpos, (int)crel.rsize+1);
  2730.         
  2731.         switch  (crel.rsegment)  {
  2732.         case  RTEXT:
  2733.             if  (lval + trelpos - outf->ef_tbase != mval)
  2734.                 lclash("Trel");
  2735.             continue;
  2736.         case  RDATA:
  2737.             if  (donedrel)  {
  2738.                 if  (lval + drelpos - outf->ef_dbase != mval)
  2739.                     lclash("Drel");
  2740.             }
  2741.             else  {
  2742.                 donedrel++;
  2743.                 drelpos = mval - lval + outf->ef_dbase;
  2744.             }
  2745.             continue;
  2746.         case  RBSS:
  2747.             if  (donebrel)  {
  2748.                 if  (lval + brelpos - outf->ef_bbase != mval)
  2749.                     lclash("brel");
  2750.             }
  2751.             else  {
  2752.                 donebrel++;
  2753.                 brelpos = mval - lval + outf->ef_bbase;
  2754.             }
  2755.             continue;
  2756.         case  REXT:
  2757.             if  (crel.rsymbol >= outf->ef_stcnt)
  2758.                 lclash("Bad sy no");
  2759.             csymb = outf->ef_stvec[crel.rsymbol];
  2760.             if  (csymb == NULL)
  2761.                 continue;
  2762.             switch  (csymb->s_type)  {
  2763.             case  N_UNDF:
  2764.                 reassign(csymb, mval - lval);
  2765.                 break;
  2766.             case  N_ABS:
  2767.                 if  (lval + csymb->s_value != mval)
  2768.                     lclash("abs rel");
  2769.                 break;
  2770.             case  N_TEXT:
  2771.                 if  (lval + csymb->s_value != mval)
  2772.                     lclash("text rel");
  2773.                 break;
  2774.             case  N_DATA:
  2775.                 if  (lval + csymb->s_value != mval)
  2776.                     lclash("data rel");
  2777.                 break;
  2778.             case  N_BSS:
  2779.                 if  (lval + csymb->s_value != mval)
  2780.                     lclash("bss rel");
  2781.                 break;
  2782.             case  COMM:
  2783.                 reassign(csymb, mval - lval);
  2784.                 break;
  2785.             }
  2786.             mtstr.t_relsymb = csymb;
  2787.             mtstr.t_reldisp = lval;
  2788.             break;
  2789.         }
  2790.     }
  2791.     
  2792.     /*
  2793.      *    Relocate data and bss if possible.
  2794.      */
  2795.     
  2796.     if  (donebrel)  {
  2797.         zapdat(N_BSS, brelpos);
  2798.         dhere++;
  2799.     }
  2800.     
  2801.     if  (!donedrel)
  2802.         return;
  2803.         
  2804.  
  2805.     zapdat(N_DATA, drelpos);
  2806.     
  2807.     /*
  2808.      *    And now repeat all that for data relocations if possible
  2809.      */
  2810.     
  2811.     size  =  filhdr.rdsize;
  2812.     
  2813.     (void) lseek(inf, RDATAPOS + offset, 0);
  2814.     for  (;  size >= sizeof(struct reloc); size -= sizeof(crel))  {
  2815.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  2816.             lclash("Rd drel");
  2817.  
  2818.         if  (crel.rsize != RLONG)
  2819.             continue;
  2820.  
  2821.         pos = crel.rpos + outf->ef_dbase;
  2822.         mpos = crel.rpos + drelpos;
  2823.         getde(&mainfile, mpos, &mdstr);
  2824.         lval = getdw(outf, pos, (int)crel.rsize+1);
  2825.         mval = getdw(&mainfile, mpos, (int)crel.rsize+1);
  2826.         switch  (crel.rsegment)  {
  2827.         case  RTEXT:
  2828.             if  (lval + trelpos - outf->ef_tbase != mval)
  2829.                 lclash("Trel-d");
  2830.             continue;
  2831.         case  RDATA:
  2832.             if  (lval + drelpos - outf->ef_dbase != mval)
  2833.                 lclash("Drel-d");
  2834.             continue;
  2835.         case  RBSS:
  2836.             if  (donebrel)  {
  2837.                 if  (lval + brelpos - outf->ef_bbase != mval)
  2838.                     lclash("brel");
  2839.             }
  2840.             else  {
  2841.                 donebrel++;
  2842.                 brelpos = mval - lval + outf->ef_bbase;
  2843.             }
  2844.             continue;
  2845.         case  REXT:
  2846.             if  (crel.rsymbol >= outf->ef_stcnt)
  2847.                 lclash("Bad sy no");
  2848.             csymb = outf->ef_stvec[crel.rsymbol];
  2849.             if  (csymb == NULL)
  2850.                 continue;
  2851.             switch  (csymb->s_type)  {
  2852.             case  N_UNDF:
  2853.                 reassign(csymb, mval - lval);
  2854.                 break;
  2855.             case  N_ABS:
  2856.                 if  (lval + csymb->s_value != mval)
  2857.                     lclash("abs rel");
  2858.                 break;
  2859.             case  N_TEXT:
  2860.                 if  (lval + csymb->s_value != mval)
  2861.                     lclash("text rel");
  2862.                 break;
  2863.             case  N_DATA:
  2864.                 if  (lval + csymb->s_value != mval)
  2865.                     lclash("data rel");
  2866.                 break;
  2867.             case  N_BSS:
  2868.                 if  (lval + csymb->s_value != mval)
  2869.                     lclash("bss rel");
  2870.                 break;
  2871.             case  COMM:
  2872.                 reassign(csymb, mval - lval);
  2873.                 break;
  2874.             }
  2875.             mtstr.t_relsymb = csymb;
  2876.             mtstr.t_reldisp = lval;
  2877.             break;
  2878.         }
  2879.     }
  2880.  
  2881.     if  (dhere || !donebrel)
  2882.         return;
  2883.  
  2884.     zapdat(N_BSS, brelpos);
  2885. }
  2886. SHAR_EOF
  2887. if test 18429 -ne "`wc -c < 'robj.c'`"
  2888. then
  2889.     echo shar: error transmitting "'robj.c'" '(should have been 18429 characters)'
  2890. fi
  2891. fi
  2892. exit 0
  2893. #    End of shell archive
  2894.